【问题标题】:Non cryptographic hash function for list列表的非加密哈希函数
【发布时间】:2013-05-05 23:24:07
【问题描述】:

您好,谁能推荐一个 hash 函数来获取整数列表并返回一个新的integer? 它应该快速评估并且或多或少地抗碰撞。 我打算在近似搜索算法中使用它(例如 LSH)

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

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

有人知道为什么它具有碰撞抗性吗?我猜大概是 31 是素数,但不知道如何证明。

【问题讨论】:

标签: java algorithm hash cryptography


【解决方案1】:

你的公式有误(倒数),实际上是:

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

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

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

(和 Java 的整数一样,结果取模 2^32。)

Java 的 hashCode() 用于 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 也是。

【讨论】:

  • 我认为主要关心的是计算速度也应该相对较快;使用 SHA-256 哈希可能会“稍微”降低性能 :)
猜你喜欢
  • 2021-01-23
  • 2020-08-08
  • 2018-07-12
  • 2021-11-19
  • 2013-07-27
  • 2017-11-15
  • 2012-01-13
  • 2011-10-27
相关资源
最近更新 更多