你们可以建议一个哈希函数来获取整数列表并返回一个新的integer
吗?
它应该快速评估并且或多或少地具有抗冲击性。
我计划在近似搜索算法(例如LSH)中使用它
Java的hashCode()
列表使用以下公式:
31 + SUM 31^(i+1) *a[i]
有人知道为什么碰撞抗拒?我想这是关于31是一个素数,但不知道如何证明它。
答案 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。