是否保证python中的hash()
函数对于给定的输入总是相同的,而不管它在何时何地输入?到目前为止-仅仅是试错法-答案似乎是肯定的,但是很高兴了解其工作原理的内部。例如,在测试中:
$ python
>>> from ingest.tpr import *
>>> d=DailyPriceObj(date="2014-01-01")
>>> hash(d)
5440882306090652359
>>> ^D
$ python
>>> from ingest.tpr import *
>>> d=DailyPriceObj(date="2014-01-01")
>>> hash(d)
5440882306090652359
答案 0 :(得分:3)
__hash__
方法的协定要求它在给定的Python运行中必须一致。 没有保证跨不同的Python运行 是一致的,实际上,对于内置str
,类似bytes
类型和datetime.datetime
对象(可能还有其他对象),则将哈希值与每次运行的值混合使用,这样,在不同的Python运行中,相同的输入几乎就不会相同。
答案 1 :(得分:1)
不,这取决于过程。如果需要持久性哈希,请参见Persistent Hashing of Strings in Python。
根据__hash__的文档,截断取决于平台:
hash()将对象的自定义__hash __()方法返回的值截断为Py_ssize_t的大小。在64位版本上通常为8个字节,在32位版本上通常为4个字节。
相同文档中的盐散列(ShadowRanger的回答):
默认情况下,str,bytes和datetime对象的__hash __()值会以不可预测的随机值“成盐”。尽管它们在单个Python进程中保持不变,但是在重复调用Python之间是不可预测的。 这旨在提供保护,防止由于精心选择的输入而导致的拒绝服务,这些输入利用了dict插入的最坏情况的性能O(n ^ 2)复杂性。有关详细信息,请参见http://www.ocert.org/advisories/ocert-2011-003.html。
答案 2 :(得分:1)
可散列性的必要条件是,对于等价对象,该值始终始终相同(在解释器的一次运行中 )。 / p>
当然,没有什么可以阻止您忽略此要求。但是,如果您突然想将对象存储在字典或集中,则可能会出现问题。
实现自己的类时,可以定义方法__eq__
和__hash__
。我已经使用了字符串的多项式哈希函数和通用哈希函数系列的哈希函数。
通常,特定对象的哈希值在解释器之间不应该更改。但是对于许多数据类型,这是正确的。实施此程序的原因之一是,它很难找到并进行抗哈希测试。
对于数字类型,数字
x
的哈希基于归约x
的模数以质数P = 2**_PyHASH_BITS - 1
为模。它被设计成 即使hash(x) == hash(y)
和x
在数值上相等,y
x
和y
具有不同的类型。
a = 123456789
hash(a) == 123456789
hash(a + b * (2 ** 61 - 1)) == 123456789