不同语言版本的 Murmurhash 得到不同的结果

Murmurhash of different language version get different result

我已经在 java(jedis 和 guava)中尝试了三个版本的 murmurhash,go 和 python。 java(guava),go 和 python 版本的结果输出相同的哈希码,但与 java(jedis) 不同。 所有的 murmurhash 代码如下所示。我对结果感到困惑。我看过这个,在java里用了Long.reverseBytes,还是和别人不一样。那么我应该怎么做才能使 murmurhash 的所有输出保持不变。谢谢~

1. java 版本(绝地武士)

java gradle compile group: 'redis.clients', name: 'jedis', version: '3.1.0'

import redis.clients.jedis.util.MurmurHash;

MurmurHash murmurhash = new MurmurHash();
long h = murmurhash.hash("foo");
System.out.println(h);
System.out.println(Long.reverseBytes(h));

输出:

-7063922479176959649

6897758107479832477

2。 golang 版本

import "github.com/spaolacci/murmur3"

foo := int64(murmur3.Sum64WithSeed([]byte("foo"), 0x1234ABCD))
fmt.Println(foo)

输出:

-5851200325189400636

3。 python版本

pip install mmh3

import mmh3

foo = mmh3.hash64('foo', seed=0x1234ABCD, signed=True)
print(foo)

输出:

-5851200325189400636

4。 java(番石榴)

java gradle compile group: 'com.google.guava', name: 'guava', version: '28.0-jre'

import com.google.common.hash.Hashing

long foo = Hashing.murmur3_128(0x1234ABCD).hashString("foo", charset.forName("UTF-8")).asLong();
System.out.println(foo);

输出:

-5851200325189400636

TL;DR
Jedis 使用 Murmur2,而其他库使用 Murmur3。


我在将一些代码从 Java/Jedis 迁移到 Golang 时也爱上了它。

差异是由于不同版本的杂音。 直到今天,Jedis 使用 Murmur2(参见 source code and documentation),而上述其他库使用 Murmur3。

除了查看comments/code,我还使用Murmur2 reference implementation验证了这一点。使用相同的种子和密钥会导致与您的 Jedis 示例完全相同的结果。

代码片段:

const char *key = "foo";

uint64_t result = MurmurHash64A(key, std::strlen(key), 0x1234ABCD);

std::cout << "  result (unsigned): " << result << std::endl;
std::cout << "    result (signed): " << (long) result << std::endl;
std::cout << "reversed byte order: " << __builtin_bswap64(result) << std::endl;

输出:

    result (unsigned): 11382821594532591967
      result (signed): -7063922479176959649
  reversed byte order:  6897758107479832477