用于列表的非加密哈希函数

时间:2013-05-11 11:10:18

标签: java algorithm hash cryptography

你们可以建议一个哈希函数来获取整数列表并返回一个新的integer吗? 它应该快速评估并且或多或少地具有抗冲击性。 我计划在近似搜索算法(例如LSH)中使用它

Java的hashCode()列表使用以下公式:

31 + SUM 31^(i+1) *a[i]

有人知道为什么碰撞抗拒?我想这是关于31是一个素数,但不知道如何证明它。

1 个答案:

答案 0 :(得分:1)

你的公式错了(倒计时),实际上是:

SUM  31^(n-1-i) * a[i]

其中n是列表的长度,我们也使用[-1] = 1.或者,如果你想单独使用它,

31^n + SUM  31^(n-1-i) * a[i]

(结果取模2 ^ 32,像往常一样用于Java的内容。)

Java hashCode() for List(specified in java.util.List,并且应该由此类的每个实现实现)在加密意义上是不是抗冲突的。也就是说, 很难找到碰撞。

给定具有多个元素的任何整数列表,我们可以将其中一个增加1并将下一个减少31(或者相反),并使用相同的哈希代码来增加第二个列表。

例如,两个列表[1, 0][0, 31]具有相同的哈希码992 = 31·32 = (1·31 + 1)·31 + 0 = (1·31 + 0)·31 + 31

它对意外碰撞有一些弱抵抗,这确实与31是素数(即没有实际除数)这一事实有关,并且“自然出现的”整数列表(或其他对象的哈希码)不倾向于只是这个数量不同。

当然,如果我们构建列表列表,每个列表都使用相同的哈希码策略,我们就可以轻松获得冲突:[ [0, 1], [0, 0] ][ [0, 0], [1, 0] ]具有相同的哈希码31³+ 2· 31²+ 31 = 31744。