来自Scala和Guava的Murmur3的不同结果
发布时间:2020-12-16 10:00:00 所属栏目:安全 来源:网络整理
导读:我试图使用Murmur3算法生成哈希值.散列是一致的,但它们是由 Scala和Guava返回的不同值. class package$Test extends FunSuite { test("Generate hashes") { println(s"Seed = ${MurmurHash3.stringSeed}") val vs = Set("abc","test","bucket",111.toString)
我试图使用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字符转换为int不同于Guava的hashUnencodedChars(没有Charset的hashString被重命名为).
斯卡拉: val data = (str.charAt(i) << 16) + str.charAt(i + 1) 番石榴: int k1 = input.charAt(i - 1) | (input.charAt(i) << 16); 在Guava中,索引i处的char成为int的16个最低有效位,而i 1处的char成为最重要的16位.在Scala实现中,这是相反的:i处的char是最重要的,而i 1处的char是最不重要的. (Scala实现使用而不是|的事实也可能是我想象的重要.) 请注意,Guava实现相当于使用ByteBuffer.putChar(c)两次将两个字符放入一个小端字节ByteBuffer,然后使用ByteBuffer.getInt()来取回一个int值. Guava实现也等同于使用UTF-16LE将字符编码为字节并对这些字节进行散列. Scala实现不等同于在JVM需要支持的任何标准字符集中编码字符串.一般来说,我不确定Scala有什么先例(如果有的话)这样做. 编辑: Scala实现还做了另一件与Guava实现不同的事情:它将被散列的字符数传递给finalizeHash方法,其中Guava的实现将字节数传递给等效的fmix方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |