27

我相信这个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

谁能告诉我这是一个错误还是我误解了什么。

4

5 回答 5

36

hash()每次启动最新版本(Python3.3+)的新实例时默认随机化,以防止字典插入 DOS 攻击

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

如果您想要每次都对同一事物进行哈希处理,请使用 hashlib 中的哈希值之一

>>> import hashlib
>>> hashlib.algorithms
('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
于 2013-06-19T13:34:47.730 回答
10

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

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

CPythonid()是内存中的地址 - 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

有一个答案here某处解释那个...

于 2013-06-19T13:43:21.127 回答
1

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

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

于 2013-06-19T13:58:44.117 回答
1

像 int 这样的东西的散列依赖于 id(),它不能保证在运行之间或解释器之间保持不变。也就是说,hash(int) 在程序运行期间将始终产生相同的结果,但在同一平台或不同平台上的运行之间可能不会比较相等。

顺便说一句,虽然哈希随机化在 Python 中可用,但默认情况下它是禁用的。由于您的字符串和数字的哈希值相等,显然这不是这里的问题。

于 2013-06-19T13:31:53.707 回答
0

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

目前仅对字符串实施哈希随机化——因为它被认为是从外部捕获的最有可能受到攻击的数据类型。

相同的 freezeset 在不同的机器甚至不同的进程中始终产生相同的哈希值

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

于 2018-05-17T09:35:52.007 回答