【发布时间】:2016-10-03 09:51:20
【问题描述】:
我一直在玩 Python 的 hash function。对于小整数,它总是出现hash(n) == n。然而,这并没有扩展到大量:
>>> hash(2**100) == 2**100
False
我并不感到惊讶,我知道 hash 的取值范围是有限的。这个范围是多少?
我尝试使用binary search 找到最小的数字hash(n) != n
>>> import codejamhelpers # pip install codejamhelpers
>>> help(codejamhelpers.binary_search)
Help on function binary_search in module codejamhelpers.binary_search:
binary_search(f, t)
Given an increasing function :math:`f`, find the greatest non-negative integer :math:`n` such that :math:`f(n) \le t`. If :math:`f(n) > t` for all :math:`n \ge 0`, return None.
>>> f = lambda n: int(hash(n) != n)
>>> n = codejamhelpers.binary_search(f, 0)
>>> hash(n)
2305843009213693950
>>> hash(n+1)
0
2305843009213693951有什么特别之处?我注意到它小于sys.maxsize == 9223372036854775807
编辑:我使用的是 Python 3。我在 Python 2 上运行了相同的二进制搜索,得到了不同的结果 2147483648,我注意到它是 sys.maxint+1
我还用[hash(random.random()) for i in range(10**6)] 来估计哈希函数的范围。最大值始终低于上述 n。比较最小值,似乎 Python 3 的哈希值总是正值,而 Python 2 的哈希值可以取负值。
【问题讨论】:
-
你检查过数字的二进制表示吗?
-
'0b1111111111111111111111111111111111111111111111111111111111111'很好奇!所以
n+1 == 2**61-1 -
似乎与系统相关。使用我的 python,整个 64 位 int 范围的哈希为
n。 -
请注意散列值的规定用途:它们用于在字典查找期间快速比较字典键。 换句话说,实现定义的,并且由于是比许多可以具有哈希值的值短,即使在合理的输入空间中也很可能发生冲突。
-
嗯,不是
2147483647等于sys.maxint(未sys.maxint+1),并且如果 'N = 0b1111111111111111111111111111111111111111111111111111111111111' 然后不n+1 == 2**61或n == 2**61-1(未n+1 == 2**61-1)?
标签: python python-2.7 python-3.x hash python-internals