我试图编写一些代码来阻止修改列表的更新。为此,我计算值的SHA1哈希,但是当我重新启动ipython解释器时,此哈希的hexdigest()会产生不同的结果。这是为什么?
In [1]: import hashlib
In [2]: hashid = hashlib.sha1()
In [3]: hashid.update(repr(frozenset(sorted(["a","b","c"]))).encode("utf-8"))
In [4]: hashid.hexdigest()
Out[4]: '53ca01b21fd7cb1996634bb45ad74851f73c45d3'
重新初始化hashid并在同一个ipython3控制台中再次进行哈希计算时,它可以工作:
In [5]: hashid = hashlib.sha1()
In [6]: hashid.update(repr(frozenset(sorted(["a","b","c"]))).encode("utf-8"))
In [7]: hashid.hexdigest()
Out[7]: '53ca01b21fd7cb1996634bb45ad74851f73c45d3'
但是停止我的控制台并重新启动它会产生不同的结果:
In [7]: exit
rvl@laptop ~/ $ ipython3
In [1]: import hashlib
In [2]: hashid = hashlib.sha1()
In [3]: hashid.update(repr(frozenset(sorted(["a","b","c"]))).encode("utf-8"))
In [4]: hashid.hexdigest()
Out[4]: '6e5813fcb173e35e81d6138eab4d21482885e7eb'
这是为什么?如何在拥有相同的排序列表时生成相同的SHA1哈希/ hexdigest结果?
答案 0 :(得分:1)
您不能依赖repr
/ set
对象frozenset
的排序,因为这些值没有保证顺序(事实上,作为反拒绝服务功能,字符串的哈希码在同一版本的Python的不同运行之间会有所不同,导致set
排序发生变化。)
在您的frozenset
和sorted
来电之间进行切换,以获得始终如一的可重复表示。排序list
已保证订购,而frozenset
将为您提供唯一性保证:
hashid.update(repr(sorted(frozenset(["a","b","c"]))).encode("utf-8"))