python中的哈希函数

时间:2013-06-19 13:24:51

标签: python hash sl4a

我相信hash()函数在所有python解释器中都是一样的。但是当我使用python for android在我的手机上运行它时,它会有所不同。我得到哈希字符串和数字的相同哈希值,但是当我对内置数据类型进行哈希时,哈希值会有所不同。

PC Python解释器(Python 2.7.3)

>>> hash(int)
31585118
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

移动Python解释器(Python 2.6.2)

>>> hash(int)
-2146549248
>>> hash("hello sl4a")
1532079858
>>> hash(101)
101

任何人都可以告诉我这是一个错误还是我误解了什么。

5 个答案:

答案 0 :(得分:34)

默认情况下,每次启动新版本的最新版本(Python3.3 +)到prevent dictionary insertion DOS attacks时,

hash()都是随机的

在此之前,无论如何,hash()对于32位和64位版本都是不同的。

如果你想要每次都使用哈希的东西,请使用hashlib中的一个哈希

>>> import hashlib
>>> hashlib.algorithms
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')

答案 1 :(得分:9)

对于旧的python(至少,我的Python 2.7),似乎

hash(<some type>) = id(<type>) / 16

并且对于CPython id()是内存中的地址 - http://docs.python.org/2/library/functions.html#id

>>> id(int) / hash(int)                                                     
16                                                                              
>>> id(int) % hash(int)                                                 
0                                                                               

所以我的猜测是Android端口对内存地址有一些奇怪的约定?

无论如何,鉴于上述情况,类型的哈希(以及我猜的其他内置函数)在安装过程中会有所不同,因为函数位于不同的地址。

相反,值的哈希值(我认为你的意思是“非内部对象”)(在添加随机内容之前)是根据它们的值计算的,因此很可能是可重复的。

PS但是至少还有一个CPython皱纹:​​

>>> for i in range(-1000,1000):
...     if hash(i) != i: print(i)
...
-1

这里有一个答案可以解释一个......

答案 2 :(得分:1)

像int一样的哈希依赖于id(),这在运行之间或解释器之间不能保证不变。也就是说,hash(int)在程序运行期间始终会产生相同的结果,但在同一平台或不同平台上运行时可能无法进行相同的比较。

BTW,虽然Python中提供了散列随机化,但默认情况下它被禁用。由于你的字符串和数字是同等的散列,显然这不是问题所在。

答案 3 :(得分:1)

使用CPython,出于效率原因hash()对内部对象返回与id()相同的值,后者又返回对象的内存位置(“地址”)

从一个基于CPython的解释器到此类对象的其他内存位置可能会发生变化。根据您的操作系统,这可能会从一次运行变为另一次运行。

答案 4 :(得分:0)

从Python 3.3开始,默认的哈希算法创建了哈希值,这些哈希值被随机值加密,即使在同一台机器上的不同python进程之间也是如此。

目前仅针对字符串实现了哈希随机化 - 因为它被认为是从外部捕获的最可能被攻击的数据类型。

相同的冻结集在不同的机器甚至不同的进程中始终产生相同的散列值

来源:https://www.quora.com/Do-two-computers-produce-the-same-hash-for-identical-objects-in-Python