【问题标题】:Selecting parameters for string hashing选择字符串散列的参数
【发布时间】:2016-10-18 11:50:58
【问题描述】:

我最近正在阅读一篇关于字符串散列的文章。我们可以通过将字符串转换为多项式来散列字符串。

H(s1s2s3 ...sn) = (s1 + s2*p + s3*(p^2) + ··· + sn*(p^n−1)) mod M.

对 p 和 M 有什么约束才能降低碰撞概率?

  1. 对字符串的哈希函数的一个很好的要求是它应该很难找到 一对不同的字符串,最好具有相同的长度 n,具有相同的指纹。这 排除了 M

  2. 类似地,如果 gcd(M, p) > 1 那么 p 模 M 的幂可以重复 小于 n 的指数。最安全的选择是将 p 设置为 群 U(ZM) 的生成器——所有整数的群 在乘法模M下与M互质。

我无法理解上述限制。选择 M 1 如何增加碰撞?有人可以用一些例子来解释这两个吗?我只需要对这些有基本的了解。

另外,如果有人能关注M的上下界,那就绰绰有余了。 以上事实摘自以下文章string hashing mit

【问题讨论】:

    标签: string hash hashmap hashtable primes


    【解决方案1】:

    这些问题的“正确”答案涉及一定数量的数论,但查看一些极端情况以了解约束为何有用通常会很有启发意义。

    例如,让我们看看为什么我们想要 M ≥ n。作为一个极端情况,我们选择 M = 2 和 n = 4。然后看数字 p0 mod 2, p1 mod 2, p2 mod 2 和 p3 mod 2。因为这里有四个数字并且只有两个可能的余数,所以根据鸽巢原理,我们知道这些数字中至少有两个必须相等。为简单起见,我们假设 p0 和 p1 是相同的。这意味着散列函数将为前两个字符已交换的任何两个字符串返回相同的散列码,因为这些字符乘以相同的数量,这不是散列函数的理想属性。更一般地说,我们想要 M ≥ n 的原因是因为值 p0, p1, ..., pn-1 至少有区别的可能性。如果 M

    现在,让我们考虑一下为什么我们想要 gcd(M, p) = 1。作为一个极端情况,假设我们选择 p 使得 gcd(M, p) = M(也就是说,我们选择 p = M)。那么

    s0p0 + s1p1 + s2 p2 + ... + sn-1pn-1 (mod M)

    = s0M0 + s1M1 + s2M2 + ... + sn-1Mn-1 (mod M)

    = s0

    糟糕,这不好 - 这使得我们的哈希码完全等于字符串的第一个字符。这意味着如果 p 不与 M 互质(即,如果 gcd(M, p) ≠ 1),您将面临某些字符被“修改”出哈希码的风险,从而增加了冲突概率。

    【讨论】:

    • 这是一个非常漂亮的解释,带有很好的简单示例。谢谢!
    【解决方案2】:

    选择 M 1 如何增加碰撞?

    在您的哈希函数公式中,M 可以合理地用于将哈希结果限制为特定的位宽:例如M=216 用于 16 位散列,M=232 用于 32 位散列,M=2^64 用于 64 位散列。通常,在实现中实际上不需要 mod/% 操作,因为使用所需大小的无符号整数进行哈希计算会固有地执行该功能。

    我不推荐它,但有时您确实会看到人们描述的哈希函数与特定哈希表的大小完全耦合,以至于他们将结果直接修改为表大小。

    你引用的文字说:

    对字符串的哈希函数的一个很好的要求是应该很难找到一对不同的字符串,最好是具有相同长度的 n,具有相同的指纹。这排除了 M 的选择

    这在三个不同的方面似乎有点愚蠢。首先,这意味着对一段长文本进行散列需要非常长的散列值,而实际上,在选择 M 时最好考虑的是需要散列的不同文本段落的数量。

    更具体地说,如果您有 V 个不同的值要使用良好的通用散列函数进行散列,那么如果您的散列函数产生至少 V2 个不同的散列值,那么散列值的冲突将大大减少哈希值。例如,如果您要散列 1000 个值(~210),您希望 M 至少为 100 万(即至少 2*10 = 20 位散列值,可以四舍五入最高 32 位,但最好不要满足于 16 位)。阅读Birthday Problem 了解相关见解。

    其次,给定 n 是字符的数量,潜在值的数量(即不同的输入)是任何特定字符可以采用的不同值的数量,提高到 n 次方。前者可能在 26 到 256 个值之间,这取决于散列是否仅支持字母,或者说字母数字输入,或者标准与扩展 ASCII 和控制字符等,甚至更多的 Unicode。 “排除M 的方式暗示M和n之间的任何相关线性关系都是虚假的;如果有的话,当 M 低于不同的潜在输入值的数量时,它会越来越多地促进碰撞,但同样,不同输入的实际数量往往更重要。

    第三,“最好具有相同的长度 n” - 为什么这很重要?据我所知,不是。

    我没有什么可以添加到 templatetypedef 关于 gcd 的讨论中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 2020-03-17
      • 2013-11-16
      • 2011-12-25
      • 2012-09-19
      • 2016-10-25
      • 2023-01-03
      相关资源
      最近更新 更多