2015-04-29 82 views
1

我有两个不同的程序,希望分别使用Murmur3在Python和Java中哈希相同的字符串。Murmur3哈希在Python和Java实现之间的不同结果

Python版本2.7.9:

mmh3.hash128('abc') 

给出79267961763742113019008347020647561319L。

Java是番石榴18.0:

HashCode hashCode = Hashing.murmur3_128().newHasher().putString("abc", StandardCharsets.UTF_8).hash(); 

给出字符串 “6778ad3f3f3f96b4522dca264174a23b”,转换为BigInterger给137537073056680613988840834069010096699.

如何从都得到同样的结果?

感谢

回答

5

下面是如何从获得相同的结果:

byte[] mm3_le = Hashing.murmur3_128().hashString("abc", UTF_8).asBytes(); 
byte[] mm3_be = Bytes.toArray(Lists.reverse(Bytes.asList(mm3_le))); 
assertEquals("79267961763742113019008347020647561319", 
    new BigInteger(mm3_be).toString()); 

的哈希代码的字节需要被视为小尾数BigInteger解释字节大端。您大概使用new BigInteger(hex, 16)来创建BigInteger,但HashCode.toString()的输出实际上是一系列的十六进制数字对,它们以asBytes()(小端)返回的相同顺序表示散列字节。 (您也可以反转这些十六进制对以得到一个十六进制数,在传递到new BigInteger(reversedHex, 16)时产生相同的结果)。

我认为toString()的文档有点混淆,因为它指的是“big endian”。它实际上并不意味着该方法的输出是表示被解释为大端的字节的十六进制数字。

我们有一个开放的issue用于将asBigInteger()添加到HashCode