我目前正在使用hash
整数和字符串的元组(以及整数和字符串的嵌套元组等)来计算某些对象的唯一性。除非可能存在哈希冲突,否则我想知道 -hash
这些数据类型上的函数是否保证为不同版本的 Python 返回相同的结果?
问问题
3052 次
3 回答
15
不会。除了 32 位和 64 位版本的 Python 之间长期存在的差异之外,散列算法在 Python 3.3中进行了更改以解决安全问题:
默认情况下,str、bytes 和 datetime 对象的hash () 值是用不可预测的随机值“加盐”的。尽管它们在单个 Python 进程中保持不变,但它们在 Python 的重复调用之间是不可预测的。
这是为了防止由精心选择的输入引起的拒绝服务,这些输入利用 dict 插入的最坏情况性能,O(n^2) 复杂度。有关详细信息,请参阅http://www.ocert.org/advisories/ocert-2011-003.html。
更改哈希值会影响 dicts、sets 和其他映射的迭代顺序。Python 从未对这种顺序做出保证(它通常在 32 位和 64 位版本之间变化)。
因此,从 3.3 开始hash()
,甚至不能保证在同一 Python 版本的不同调用中返回相同的结果。
于 2013-05-09T00:19:58.907 回答
8
我不确定您在寻找什么,但hashlib
如果您正在寻找一致的散列,您可以随时使用。
>>> import hashlib
>>> t = ("values", "other")
>>> hashlib.sha256(str(t)).hexdigest()
'bc3ed71325acf1386b40aa762b661bb63bb72e6df9457b838a2ea93c95cc8f0c'
或者:
>>> h = hashlib.sha256()
>>> for item in t:
... h.update(item)
...
>>> h.hexdigest()
'5e98df135627bc8d98250ca7e638aeb2ccf7981ce50ee16ce00d4f23efada068'
于 2013-05-09T01:36:33.183 回答
3
不,例如。
32 位
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foobar")
-1969371895
64 位
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foobar")
3433925302934160649
于 2013-05-09T00:20:03.267 回答