Python与JavaScript中MurmurHash3 x64.hash128结果不一致问题求助
解决Python与JavaScript的MurmurHash3 x64.hash128结果不一致问题
项目开发中需要让Python和JavaScript通过x64.hash128生成的MurmurHash3哈希结果一致,但目前两边结果存在差异,使用的库分别是Python的mmh3和JavaScript的murmurHash3js。
两边测试结果
Python端测试结果
>>> mmh3.hash128('Helo', 0) 36257070446276374087060059272450503274 >>> mmh3.hash128('Helo', 0, False) 20867082311197569335197338913536872358
JavaScript端测试结果
murmurHash3.x64.hash128("Helo") '29c3815d749d726a1b46db969b492ae8'
问题原因
- 输出格式不同:Python的mmh3返回十进制整数,JavaScript返回十六进制字符串。
- 字节序差异:mmh3默认按小端序组合128位哈希值,而murmurHash3js返回的是大端序的十六进制结果。
- 符号处理差异:mmh3的第三个参数
signed控制返回有符号/无符号整数,默认True返回有符号值,False返回无符号值。
解决方法
方法1:Python端转换为匹配JavaScript的十六进制字符串
用以下代码将mmh3的结果转换为大端序十六进制字符串,和JavaScript结果完全一致:
import mmh3 def get_murmur3_hex(s, seed=0): # 获取无符号的两个64位哈希分量 h1, h2 = mmh3.hash128(s, seed, False) # 转换为16位补零的大端序十六进制字符串,再拼接 return f"{h1:016x}{h2:016x}" # 测试 print(get_murmur3_hex('Helo')) # 输出: 29c3815d749d726a1b46db969b492ae8
方法2:JavaScript端转换为匹配Python的十进制整数
如果需要在JS端得到和Python无符号整数一致的结果,使用BigInt处理(因为128位值超出Number精度范围):
function hexToUnsigned128Decimal(hexStr) { // 拆分十六进制字符串为两个64位部分 const upperHex = hexStr.slice(0, 16); const lowerHex = hexStr.slice(16); // 转换为BigInt const upper = BigInt('0x' + upperHex); const lower = BigInt('0x' + lowerHex); // 组合为128位无符号整数,对应Python mmh3.hash128(s, 0, False)的结果 return (upper << 64n) | lower; } // 测试 const hashHex = murmurHash3.x64.hash128("Helo"); console.log(hexToUnsigned128Decimal(hashHex).toString()); // 输出: 20867082311197569335197338913536872358
内容的提问来源于stack exchange,提问作者Sysy
相关产品推荐
相关产品推荐

