【问题标题】:Why multiply by a prime before xoring in many GetHashCode Implementations?为什么在许多 GetHashCode 实现中在异或之前乘以素数?
【发布时间】:2010-12-02 02:49:51
【问题描述】:

我知道在异或之前乘以一个大数应该有助于分布不均的操作数,但为什么乘数应该是素数?

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

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

【问题讨论】:

  • 我在这里并没有真正的答案(我诚实的答案是“因为 Josh Bloch 这么说!”)但eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx 读起来很有趣。
  • 为什么关闭?因子和模数显然不是一回事。
  • 我同意,我对重复问题线程或这个问题的答案不满意。这可能只是因为我还不明白答案。如果有人能提供进一步的澄清,将不胜感激。
  • 我也没有看到一个很好的理由来乘以素数。我认为没有。

标签: java .net algorithm hash


【解决方案1】:

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

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

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

但是,使用素数是一项古老的技术。这里的关键是要理解,只要您可以生成足够唯一的密钥,您也可以转移到其他散列技术。转到此处了解有关 hashes without primes 的更多信息。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 不幸的是,这是不正确的。您需要乘法组的生成器来获得最大循环。这与素数无关。
    【解决方案3】:

    我不确定您说的是哪种算法,但通常此类算法中的常数需要相对质数。否则,您会得到循环,并且结果中不会显示所有可能的值。

    在您的情况下,该数字可能不需要是质数,只需与其他一些数字相对质数,但将其设为质数可以保证这一点。它还涵盖了其他幻数发生变化的情况。

    例如,如果您正在谈论取某个数字的最后一位,则乘数不必是 2 的倍数。因此,即使不是素数,9 也可以工作。

    【讨论】:

      【解决方案4】:

      考虑最简单的乘法:x2。

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

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

      现在,乘以其他数字(非 2 的幂)并不那么明显,但或多或​​少仍然存在相同的问题。原始数据是完整的,或者是经过简单转换的。 (比如x5就是左移两位,然后加在原来的数据上)。

      GetHashCode 的重点是尽可能随机地分布数据。乘以素数可以保证答案不会是更简单的转换,例如位移或向自身添加数字。

      【讨论】:

      • @abelenky:字符串s 的更常见哈希之一是31 * s[0] + 31^2 * s[1] + ... + 31^(n - 1) * s[n-1]31 是素数。乘以31 与位移和减法相同(即a * 31 = (a << 5) - a)。那很简单。所有这一切都是为了指出,使用素数的原因不仅仅是为了混淆数据。
      • 这个散列但以 33 作为乘数被称为 djb 散列。由于伯恩斯坦是数论专家,他不使用素数当然不是偶然的。
      • @Accipitridae:使用 31 是素数的一个主要缺点是一对匹配的连续字符的哈希贡献将是 32 的倍数,实际上会丢失 5 位。使用 33 会使贡献是 34 的倍数,只会丢失一位。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2021-09-03
      • 2011-02-23
      • 2016-09-06
      • 1970-01-01
      • 2021-06-25
      • 2014-11-08
      相关资源
      最近更新 更多