Python和Java实现的Murmur3哈希结果不同

3

我有两个不同的程序,希望使用Python和Java中的Murmur3哈希相同的字符串。

Python版本2.7.9:

mmh3.hash128('abc')

返回79267961763742113019008347020647561319L。

Java是Guava 18.0:

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

将字符串 "6778ad3f3f3f96b4522dca264174a23b" 转换为大整数,得到的结果是 137537073056680613988840834069010096699。

如何从两者中获得相同的结果?

谢谢

2个回答

7

以下是如何从两者中获得相同的结果:

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()的文档有些令人困惑,因为它提到了“大端序”的方式,但它并不实际意味着该方法的输出是表示字节以大端序解释的十六进制数字。
我们为向HashCode添加asBigInteger()而打开了问题

4

如果有人对反向答案感兴趣,即将Python输出转换为Java输出:

import mmh3
import string

char_array = '0123456789abcdef'
mumrmur = mmh3.hash_bytes('abc')

result = [f'{string.hexdigits[(char >> 4) & 0xf]}{string.hexdigits[char & 0xf]}' for char in mumrmur]
print(''.join(result))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接