You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go与Python的Murmur3 Hash兼容性问题排查求助

解决Python与Go跨语言Murmur3 128位哈希不一致的问题

问题根源

你遇到的核心问题是不同库对Murmur3 128位哈希的字节输出顺序实现不一致:

  • Go的github.com/spaolacci/murmur3库生成128位哈希后,会将高64位字节放在前,低64位字节在后返回
  • Python的mmh3库则默认将低64位字节放在前,高64位字节在后返回

两者的哈希计算逻辑本身是一致的,只是最终的字节拼接顺序不同,导致Base64编码后的结果不匹配。

解决方案

不需要更换库,只需要调整其中一端的字节顺序,就能让结果完全一致。

方案1:调整Python代码,匹配Go的输出顺序

修改Python代码,拆分128位哈希的高低64位,按Go的顺序拼接后再编码:

import mmh3
import base64

name = "chocolate-covered-espresso-beans"
# 获取无符号128位哈希值
hash_val = mmh3.hash128(name.encode('utf-8'), signed=False)
# 拆分高64位和低64位
high_bits = (hash_val >> 64) & 0xFFFFFFFFFFFFFFFF
low_bits = hash_val & 0xFFFFFFFFFFFFFFFF
# 按Go的顺序拼接:高64位转大端字节 + 低64位转大端字节
hash_bytes = high_bits.to_bytes(8, byteorder='big') + low_bits.to_bytes(8, byteorder='big')
# 生成RawURL格式的Base64编码(去掉末尾的=)
result = base64.urlsafe_b64encode(hash_bytes).decode('utf-8').rstrip('=')
print(result)  # 输出:cLHSo2nCBxyOezviLM5gwg,与Go代码结果完全一致

方案2:调整Go代码,匹配Python的默认输出顺序

修改Go代码,调换哈希结果的高低64位顺序后再编码:

package main

import (
	"encoding/base64"
	"fmt"
	"github.com/spaolacci/murmur3"
)

func main() {
	hash := murmur3.New128()
	hash.Write([]byte("chocolate-covered-espresso-beans"))
	sum := hash.Sum(nil)
	// 调换字节顺序:原sum是[高8字节][低8字节],改为[低8字节][高8字节]
	swappedSum := append(sum[8:], sum[:8]...)
	fmt.Println(base64.RawURLEncoding.EncodeToString(swappedSum))
	// 输出:HAfCaaPSsXDCYM4s4jt7jg,与Python mmh3.hash_bytes结果完全一致
}

额外说明

  • Murmur3 128位的官方规范并未强制规定两个64位块的输出顺序,因此不同库的实现会有差异,跨语言使用时必须注意这点。
  • 如果你确实想更换库,Python可以尝试pymurmur3,Go可以使用golang.org/x/crypto/murmur3,但同样需要确认字节输出顺序是否一致。

内容的提问来源于stack exchange,提问作者bbengfort

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:25:12