Java 列表的非加密哈希函数
嗨,有人能推荐一个散列函数,该函数将获取一个整数列表并返回一个新的Java 列表的非加密哈希函数,java,algorithm,hash,cryptography,Java,Algorithm,Hash,Cryptography,嗨,有人能推荐一个散列函数,该函数将获取一个整数列表并返回一个新的整数? 它应该能够快速评估,并且或多或少具有抗碰撞能力。 我计划在近似搜索算法中使用它(例如LSH) Java的列表hashCode()使用以下公式: 31 + SUM 31^(i+1) *a[i] 有人知道它为什么能抵抗碰撞吗?我猜它大约是31,是一个素数,但不知道如何证明它。你的公式错了(它倒计时),它实际上是: SUM 31^(n-1-i) * a[i] 其中n是列表的长度,我们也使用[-1]=1。或者,如果你想把它分
整数
?
它应该能够快速评估,并且或多或少具有抗碰撞能力。
我计划在近似搜索算法中使用它(例如LSH)
Java的列表hashCode()
使用以下公式:
31 + SUM 31^(i+1) *a[i]
有人知道它为什么能抵抗碰撞吗?我猜它大约是31,是一个素数,但不知道如何证明它。你的公式错了(它倒计时),它实际上是:
SUM 31^(n-1-i) * a[i]
其中n
是列表的长度,我们也使用[-1]=1。或者,如果你想把它分开
31^n + SUM 31^(n-1-i) * a[i]
(结果取模2^32,与Java的ints一样。)
Java的hashCode()
for 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。您想搜索关于哈希的单词“雪崩”。这是最常用于防撞的术语。从这里开始:我认为主要的问题是,计算速度也应该相对较快;使用SHA-256哈希可能会“非常轻微地”破坏性能: