我们有两个不同的库,一个在 Python 中,一个在 Go 中,它们需要以相同的方式计算 murmur3 哈希。不幸的是,无论我们多么努力,我们都无法让库产生相同的结果。从this SO question about Java and Python看来,兼容性不一定是直截了当的。
现在我们正在使用 python mmh3 和 Go github.com/spaolacci/murmur3 库。
开始:
hash := murmur3.New128()
hash.Write([]byte("chocolate-covered-espresso-beans")
fmt.Println(base64.RawURLEncoding.EncodeToString(hash.Sum(nil)))
// Output: cLHSo2nCBxyOezviLM5gwg
在 Python 中:
name = "chocolate-covered-espresso-beans"
hash = mmh3.hash128(name.encode('utf-8'), signed=False).to_bytes(16, byteorder='big', signed=False)
print(base64.urlsafe_b64encode(hash).decode('utf-8').strip("="))
# Output: jns74izOYMJwsdKjacIHHA (big byteorder)
hash = mmh3.hash128(name.encode('utf-8'), signed=False).to_bytes(16, byteorder='little', signed=False)
print(base64.urlsafe_b64encode(hash).decode('utf-8').strip("="))
# Output: HAfCaaPSsXDCYM4s4jt7jg (little byteorder)
hash = mmh3.hash_bytes(name.encode('utf-8'))
print(base64.urlsafe_b64encode(hash).decode('utf-8').strip("="))
# Output: HAfCaaPSsXDCYM4s4jt7jg
在 Go 中,
murmur3
返回一个 uint64
所以我们假设 signed=False
在 Python 中;但是我们也尝试了signed=True
但没有得到匹配的哈希值。
我们对不同的库开放,但想知道我们的 Go 或 Python 从字符串计算 base64 编码哈希的方法是否有问题。任何帮助表示赞赏。
第一个 Python 结果几乎是正确的。
>>> binascii.hexlify(base64.b64decode('jns74izOYMJwsdKjacIHHA=='))
b'8e7b3be22cce60c270b1d2a369c2071c'
开始:
x, y := murmur3.Sum128([]byte("chocolate-covered-espresso-beans"))
fmt.Printf("%x %x\n", x, y)
结果:
70b1d2a369c2071c 8e7b3be22cce60c2
所以两个词的顺序颠倒了。要在 Python 中获得相同的结果,您可以尝试类似的方法:
name = "chocolate-covered-espresso-beans"
hash = mmh3.hash128(name.encode('utf-8'), signed=False).to_bytes(16, byteorder='big', signed=False)
hash = hash[8:] + hash[:8]
print(base64.urlsafe_b64encode(hash).decode('utf-8').strip("="))
# cLHSo2nCBxyOezviLM5gwg