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 &lt;&lt; 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 的原因?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 5381 和 33 在 djb2 算法中如此重要?

Dan Bernstein 的 Djb2 哈希函数:当我们只能乘以 33 时,为啥还要使用按位运算符?

c_cpp C中的哈希映射实现,带有djb2哈希函数

常见的哈希算法和应用

c_cpp 在C中进行djb2哈希测试,使控制台能够测试哈希值

我如何将 djb2 映射到哈希表?