为什么只使用素数作为Hash函数除法的方法

时间:2012-08-24 02:57:15

标签: hash modulo

使用除法方法进行散列意味着h(k)= k mod m。我读了那个

  

m不应该是2的幂。这是因为如果m = 2 ^ p,则h变为   只是k的最低位。通常我们选择m作为素数   数字不太接近2的幂。

有人可以用一个小例子解释最低位的部分吗?我认为所有(mod m)确实是它将结果包裹在范围m周围。如果m是2的幂,那么无论如何都无法看到问题。

2 个答案:

答案 0 :(得分:4)

计算机中的所有数据都存储为二进制数据。二进制数写在base-2中。

如果您对数据进行哈希处理,则需要创建易于比较的指纹。如果我们有类似的数据与原始数据不完全相同,则不应创建相同的指纹(哈希)。

猜猜如果使用m m = 2^p (p is int >= 0),会发生什么。因为例如2 ^ 7是2 ^ 4的倍数,所以从2 ^ 4离开的所有位将减少为0.您切断了部分数据。这意味着如果二进制数的最左边的数据不同,它们将创建相同的散列。

示例:

k:    1111111111010101
m:    0000000001000000 (2^6)
k(m): 0000000000010101

现在为此做同样的事情:

k:    0000000000010101
m:    0000000001000000 (2^6)
k(m): 0000000000010101
嘿,这是相同的哈希!这正是为什么选择远离2 ^ p的数字的原因。这样,最左边的位在计算散列时很重要,并且两个相似的数据块创建相同的散列的可能性要小得多。

答案 1 :(得分:0)

除数的余数可以通过重复删除除数直到要除数小于除数来计算。对于二进制数和两个除数的幂,此减法仅影响左侧的位,使其为0,但使右侧的位保持不变。

  1110001111100001₂   58337
- 0000000100000000₂      2⁸
= 1110001011100001₂   58081
___________________________

  1110001011100001₂   58081
- 0000000100000000₂      2⁸
- 0000000100000000₂      2⁸
  ...
= 0000000011100001₂   57569

当除数不均匀时,反复删除除数时,所有低位会受到影响:

  1110001111100001₂   58337
- 0000000011000011₂     195
= 1110001100011110₂   58142
___________________________

  1110001111100001₂   58337
- 0000000011000011₂     195
- 0000000011000011₂     195
  ...
= 0000000000100000₂      32

请注意,除数不能被2整除就足够了,因为每个2的因数会将二进制数向左移动一位数字,而减法只能在左边改变数字,而不能在右边改变数字。

除数与2的幂的距离越远,即数字等于0和1越多,则每次减法都会影响余数的位数。例如,这意味着模量78985(10011010010001001²)远远大于65537(10000000000000001²),即使它不是素数,而65537也不是。

这适用于散列为“差”的情况,即散列在所有输出位中的分布不均。如果我们有good hash,则可以使用所有哈希表大小,因此可以使用我们想要的除数,以及可以使用诸如fastrange之类的范围缩小方法。


*通常实际上并不是这样计算的,但是结果是等效的