python的哈希函数在不同版本中是否保持相同?

时间:2013-05-09 00:07:16

标签: python hash compatibility backwards-compatibility

我目前在整数和字符串元组(以及整数和字符串的嵌套元组等)上使用hash来计算某些对象的唯一性。除非可能存在哈希冲突,我想 - 这些数据类型的hash函数是否保证为不同版本的Python返回相同的结果?

3 个答案:

答案 0 :(得分:9)

没有。除了32位和64位版本的Python之间存在长期差异外,还有用于解决安全问题的散列算法was changed in Python 3.3

  

默认情况下,str,bytes和datetime对象的哈希()值使用不可预测的随机值“加盐”。尽管它们在单个Python进程中保持不变,但在重复调用Python之间无法预测它们。

     

这旨在提供针对由精心选择的输入引起的拒绝服务的保护,该输入利用dict插入的最坏情况性能,O(n ^ 2)复杂度。有关详细信息,请参阅http://www.ocert.org/advisories/ocert-2011-003.html

     

更改散列值会影响dicts,集和其他映射的迭代顺序。 Python从未对这种排序做出保证(通常在32位和64位版本之间有所不同)。

因此,从3.3开始,hash()甚至不能保证在相同Python版本的不同调用中返回相同的结果。

答案 1 :(得分:4)

我不确定您在寻找什么,但如果您正在寻找一致的散列效果,则可以随时使用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'

答案 2 :(得分: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