不同语言版本的 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
我已经在 java(jedis 和 guava)中尝试了三个版本的 murmurhash,go 和 python。 java(guava),go 和 python 版本的结果输出相同的哈希码,但与 java(jedis) 不同。
所有的 murmurhash 代码如下所示。我对结果感到困惑。我看过这个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