DJB 哈希函数中数字 5381 的原因?
Posted
技术标签:
【中文标题】DJB 哈希函数中数字 5381 的原因?【英文标题】:Reason for the number 5381 in the DJB hash function? 【发布时间】:2012-05-28 14:25:45 【问题描述】:谁能告诉我为什么在 DJB 哈希函数中使用数字 5381?
DJB哈希函数定义为:
h 0 = 5381
h i = 33h i - 1 + s i
这是一个 C 实现:
unsigned int DJBHash(char* str, unsigned int len)
unsigned int hash = 5381;
unsigned int i = 0;
for(i = 0; i < len; str++, i++)
hash = ((hash << 5) + hash) + (*str);
return hash;
【问题讨论】:
它是一个大素数,在大多数哈希算法中用作乘数以分散值。 【参考方案1】:5381 只是一个数字,在测试中产生了fewer collisions 和better avalanching。您会在几乎所有哈希算法中找到“神奇常数”。
【讨论】:
那些互换的网址让我笑了。 @High 我很高兴你很幽默 :) 幸运的是,交换 URL 非常容易,因为我只需要切换数字。 我无法理解上面的幽默。 问题是它是如何减少碰撞的?我也放声大笑。而且,提问的人在没有任何证据的情况下接受了答案!!!! djb2(如 fnv1a)实际上有 bad avalanche/distribution。它们甚至不符合非严格的雪崩标准,这需要更少的计算能力来计算。但他们确实有不错的碰撞率。 :) 通常,碰撞率与其雪崩行为有关,这意味着 djb2 不如其他选择好。所有位越接近伪随机,任何两个值匹配的可能性就越小。【参考方案2】:我偶然发现了一个comment,它揭示了 DJB 的工作:
/*
* DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
*
* This is Daniel J. Bernstein's popular `times 33' hash function as
* posted by him years ago on comp.lang.c. It basically uses a function
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
* known hash functions for strings. Because it is both computed very
* fast and distributes very well.
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as RSE did now) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
* with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
* advantage to the remaining numbers in the large set of possible
* multipliers: their multiply operation can be replaced by a faster
* operation based on just one shift plus either a single addition
* or subtraction operation. And because a hash function has to both
* distribute good _and_ has to be very fast to compute, those few
* numbers should be preferred and seems to be the reason why Daniel J.
* Bernstein also preferred it.
*
*
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
这是一个与您正在查看的哈希函数略有不同的哈希函数,尽管它确实使用了 5381 幻数。链接目标处该注释下方的代码已展开。
然后我找到this:
Magic Constant 5381: 1. odd number 2. prime number 3. deficient number 4. 001/010/100/000/101 b
还有this 对Can anybody explain the logic behind djb2 hash function? 的回复,它引用了DJB 本人的post 到一个提到5381 的邮件列表(摘自该答案摘录在这里):
[...] 实际上任何好的乘数都可以。我觉得你很担心 关于 31c + d 不涵盖任何合理的哈希范围的事实 如果 c 和 d 介于 0 和 255 之间,则值。这就是为什么,当我发现 33 哈希函数并开始在我的压缩器中使用它,我开始 哈希值为 5381。我想你会发现这就像 以及 261 乘数。
【讨论】:
谢谢 - 最后一条评论是 5381 的重点。 它们并没有“略有不同”。(x << 5) + x
是按位乘法。相当于x * 33
!在某些系统上使用按位方法更快,或者是乘法的唯一方法。【参考方案3】:
我发现这个数字的一个非常有趣的特性可能就是它的原因。
5381 是第 709 个素数。 709 是第 127 个素数。 127 是第 31 个素数。 31 是第 11 个素数。 11 是第 5 个素数。 5 是第三个素数。 3 是第二个素数。 2 是第一个素数。
5381 是第一个发生 8 次的数字。第 5381 个素数可能超过有符号整数的限制,因此最好停止链。
【讨论】:
oeis.org/search?q=5381 第 5381 个素数并不接近有符号整数的极限。 @evilotto 在这段代码中,他采用了 unsigned int 并且可以存储值 52711。 @JakubKaszycki 我在休闲数学中发现了它 就是整数序列在线百科全书中的sequence A007097。以上是关于DJB 哈希函数中数字 5381 的原因?的主要内容,如果未能解决你的问题,请参考以下文章
Dan Bernstein 的 Djb2 哈希函数:当我们只能乘以 33 时,为啥还要使用按位运算符?