Hash算法问题:JavaScript转Python代码后哈希结果不一致求解决
实现JavaScript与Python一致的哈希函数
要实现和JavaScript的str_hash函数结果完全一致的Python哈希函数,当前Python版本输出超大整数,和JS返回的负整数哈希结果不符。
原JavaScript代码
function str_hash(s) { var hash = 0, i, chr; if (s.length === 0) return hash; for (i = 0; i < s.length; i++) { chr = s.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash; };
输出示例:-34998534
错误的Python尝试代码
def get_hash(s): h = 0 if not s: return h for i in range(0, len(s)): h = ((h << 5) - h) + i h |= 0 return h print(get_hash('PUT LONG STRING HERE'))
输出示例:349832894283058945028049523548405975892375489743847490218348927483984793048218934148973940218340298489273942374902938490238482942930729487210948239407329403082738940214
修正后的Python代码
def str_hash(s): h = 0 if not s: return h for char in s: chr_code = ord(char) h = ((h << 5) - h) + chr_code # 模拟JavaScript的32位有符号整数溢出 h = h & 0xFFFFFFFF # 截断为32位无符号整数 # 转换为有符号整数 if h >= 0x80000000: h -= 0x100000000 return h # 测试示例 print(str_hash('PUT LONG STRING HERE'))
关键修正说明
- 修复字符编码获取:原Python代码错误使用循环索引
i参与计算,应替换为每个字符的Unicode编码(对应JS的charCodeAt,Python用ord(char))。 - 模拟32位有符号整数溢出:JavaScript中
hash |= 0会强制将数值转为32位有符号整数,而Python的整数是任意精度,不会自动溢出。通过以下步骤模拟该行为:- 用
h & 0xFFFFFFFF将数值截断为32位无符号整数; - 若数值大于等于
0x80000000(32位有符号整数的正负分界点),减去0x100000000得到对应的负数值。
- 用
修改后,Python代码的输出将与JavaScript版本完全一致。
内容的提问来源于stack exchange,提问作者MrMan
相关产品推荐
相关产品推荐

