在许多GetHashCode实现中,为什么在xoring之前乘以素数?

时间:2009-09-28 19:41:21

标签: java .net algorithm hash

我知道在xoring之前乘以大量数据应该有助于分配错误的操作数,但为什么乘数应该是素数呢?

  

相关:
  Why should hash functions use a prime number modulus?

     

关闭,但不完全重复:
  Why does Java’s hashCode() in String use 31 as a multiplier?

4 个答案:

答案 0 :(得分:4)

有一个good article on the Computing Life blog详细讨论了这个主题。它最初是作为对我在问题中链接的Java hashCode()问题的响应而发布的。根据文章:

  

Primes是唯一的数字。它们的独特之处在于,素数与任何其他数字的乘积最有可能是独特的(不像当然的素数本身那样独特),因为使用素数来构成它。此属性用于散列函数。

     

给定一个字符串“Samuel”,您可以通过将每个组成数字或字母与素数相乘并将它们相加来生成唯一的哈希值。这就是使用素数的原因。

     

然而,使用素数是一种古老的技术。关键在于理解,只要您可以生成足够独特的密钥,您也可以转移到其他散列技术。有关hashes without primes的详细信息,请访问此处。

答案 1 :(得分:2)

乘以非素数具有比数字小得多的循环重复模式。如果使用素数,则保证循环重复模式至少与素数一样大。

答案 2 :(得分:1)

我不确定你所说的是哪种算法,但通常这种算法中的常数需要相对较高。否则,您将获得循环,而不是所有可能的值都显示在结果中。

在你的情况下,这个数字可能不需要是素数,只是相对于其他数字的素数,但是使它成为主要的保证。它还涵盖了其他幻数变化的情况。

例如,如果你在谈论取一些数字的最后一位,那么乘数不需要是2的倍数。所以,即使它不是素数,9也会起作用。

答案 3 :(得分:0)

考虑最简单的乘法:x2。

相当于左位移。换句话说,它确实没有“随机化”数据,只是将其转移过来。

与x4相同,或任何2的幂。原始数据完好无损,只是转移了。

现在,乘以其他数字(两个非幂)并不是那么明显,但仍然有相同的问题,或多或少。原始数据完整无缺或简单转换。 (例如,x5与left-bitshift两个位置相同,然后添加原始数据)。

GetHashCode的要点是尽可能随机地分配数据。乘以素数可以保证答案不会像位移或添加数字那样更简单。