Update
我需要python中的高性能字符串哈希函数,该函数可以生成至少具有输出[<34位的整数(64位是有意义的,但32位太少了)。在Stack Overflow上还有其他类似的问题,但是在我能找到的每一个被接受/推荐的答案中,都属于以下几类之一,这些问题都不适用(由于给定的原因。)
hash()
函数。string.__hash__()
函数用作原型来编写您自己的函数。我怀疑这将是正确的方法,只是该特定函数的效率取决于对c_mul函数的使用,该函数可以环绕32位-太小了,我无法使用!非常令人沮丧,它是如此接近完美!具有至少延伸34位长(可能为64位)的输出范围,同时在
def perturb_hash(key,n):
return hash((key,n))
谢谢!
我需要python中的高性能字符串哈希函数,该函数可生成至少具有34位输出的整数(64位是有意义的,但32位太少了)。还有其他几个...看看128-bit variant of MurmurHash3。 algorithm's page包含一些性能编号。应该可以将其纯粹地或作为C扩展移植到Python。 (更新作者建议使用128位变体,并丢弃不需要的位。)>如果MurmurHash2 64位适合您,pyfasthash package中有一个Python实现(C扩展),它包括一些其他非加密哈希变体,尽管其中一些仅提供32位输出。我为Murmur3哈希函数做了一个快速的Python包装器。 Github project is here,您可以在Python Package Index as well上找到它;它只需要一个C ++编译器即可构建;不需要增强。Update
用法示例和时间比较:
输出:
import murmur3 import timeit # without seed print murmur3.murmur3_x86_64('samplebias') # with seed value print murmur3.murmur3_x86_64('samplebias', 123) # timing comparison with str __hash__ t = timeit.Timer("murmur3.murmur3_x86_64('hello')", "import murmur3") print 'murmur3:', t.timeit() t = timeit.Timer("str.__hash__('hello')") print 'str.__hash__:', t.timeit()
15662901497824584782 7997834649920664675 murmur3: 0.264422178268 str.__hash__: 0.219163894653
使用内置的hash()函数。至少在我正在开发的机器上(具有python 2.7和64位cpu)产生的整数可容纳32位-不足以容纳我的目的。不正确。内置的哈希函数将在64位系统上生成64位哈希。这是来自Objects/stringobject.c
(Python版本2.7)的python str哈希函数:
static long string_hash(PyStringObject *a) { register Py_ssize_t len; register unsigned char *p; register long x; /* Notice the 64-bit hash, at least on a 64-bit system */ if (a->ob_shash != -1) return a->ob_shash; len = Py_SIZE(a); p = (unsigned char *) a->ob_sval; x = *p << 7; while (--len >= 0) x = (1000003*x) ^ *p++; x ^= Py_SIZE(a); if (x == -1) x = -2; a->ob_shash = x; return x; }
“字符串”:我想您希望散列Python 2.xstr
对象和/或Python3.xbytes
和/或bytearray
对象。这可能违反了您的第一个约束,但是:请考虑使用类似的东西>>(zlib.adler32(strg, perturber) << N) ^ hash(strg)
获得(32 + N)位的哈希。
如果可以使用Python 3.2,则在64位Windows上的哈希结果现在为64位值。
请谨慎使用内置的哈希函数!自Python3起,每次解释器启动时,它都会被填充不同的种子(我不知道更多细节),因此它每次都会生成不同的值-但不适用于本机数字类型。
$ python3 -c 'print(hash("Hello!"), hash(3.14))' -1756730906053498061 322818021289917443 $ python3 -c 'print(hash("Hello!"), hash(3.14))' -4556027264747844925 322818021289917443 $ python3 -c 'print(hash("Hello!"), hash(3.14))' -4403217265550417031 322818021289917443
(zlib.adler32(strg, perturber) << N) ^ hash(strg)
获得(32 + N)位的哈希。