scala - 来自 Scala 和 Guava 的 Murmur3 的不同结果

标签 scala guava consistent-hashing murmurhash

我正在尝试使用 Murmur3 算法生成哈希。散列是一致的,但它们是 Scala 和 Guava 返回的不同值。

class package$Test extends FunSuite {
  test("Generate hashes") {
    println(s"Seed = ${MurmurHash3.stringSeed}")
    val vs = Set("abc", "test", "bucket", 111.toString)
    vs.foreach { x =>
      println(s"[SCALA] Hash for $x = ${MurmurHash3.stringHash(x).abs % 1000}")
      println(s"[GUAVA] Hash for $x = ${Hashing.murmur3_32().hashString(x).asInt().abs % 1000}")
      println(s"[GUAVA with seed] Hash for $x = ${Hashing.murmur3_32(MurmurHash3.stringSeed).hashString(x).asInt().abs % 1000}")
      println()
    }
  }
}


Seed = -137723950
[SCALA] Hash for abc = 174
[GUAVA] Hash for abc = 419
[GUAVA with seed] Hash for abc = 195

[SCALA] Hash for test = 588
[GUAVA] Hash for test = 292
[GUAVA with seed] Hash for test = 714

[SCALA] Hash for bucket = 413
[GUAVA] Hash for bucket = 22
[GUAVA with seed] Hash for bucket = 414

[SCALA] Hash for 111 = 250
[GUAVA] Hash for 111 = 317
[GUAVA with seed] Hash for 111 = 958

为什么我得到不同的哈希值?

最佳答案

在我看来它像 Scala 的 hashString转换成对的 UTF-16 char转至 int与 Guava 的不同 hashUnencodedChars ( hashString 没有 Charset 被重命名为那个)。

斯卡拉:

val data = (str.charAt(i) << 16) + str.charAt(i + 1)

Guava :
int k1 = input.charAt(i - 1) | (input.charAt(i) << 16);

在 Guava 中,char在指数i成为 int 的 16 个最低有效位和 chari + 1成为最高有效的 16 位。在 Scala 实现中,情况正好相反:chari是最重要的,而 chari + 1是最不重要的。 (我想,Scala 实现使用 + 而不是 | 的事实也很重要。)

请注意,Guava 实现等效于使用 ByteBuffer.putChar(c)两次将两个字符放入小端ByteBuffer ,然后使用 ByteBuffer.getInt()返回一个 int 值。 Guava 实现也等效于使用 UTF-16LE 将字符编码为字节。并散列这些字节。 Scala 实现并不等同于以 JVM 需要支持的任何标准字符集对字符串进行编码。总的来说,我不确定 Scala 有什么先例(如果有的话)按照它的方式来做。

编辑:

Scala 实现还做了另一件与 Guava 实现不同的事情:它将被散列的字符数传递给 finalizeHash。 Guava 的实现将字节数传递给等效的方法 fmix方法。

关于scala - 来自 Scala 和 Guava 的 Murmur3 的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30196298/

相关文章:

scala - Scala 中的模式匹配 Jackson JSON

java - 为什么 guava 21.0 版本中的 Maps 不采用 java.util.function.Function 等作为参数?

algorithm - 一致性哈希有什么缺点吗?

algorithm - 在分布式哈希表中的节点连接期间优化键空间分区

json - 如何在 akka-http 中编码和解码 mongo ObjectId

scala - Scala 中创造性和有用的运算符使用示例

java - Guava 服务在状态为 STARTING 时停止

java - 有没有办法连接字符串,每个字符串都有一个特定的周围字符串?

python - python-memcached 是否支持一致的哈希和二进制协议(protocol)?

scala - 如何从光滑的查询创建类实例?