python3 兼容python2 的hash函数
背景
最近公司在python2切python3,在这个过程中发现内置的hash函数返回值有差异。具体差异可以查看下图
可以发现,在python2中,每次hash出来的值是相同的,但在python3中却不是,经过测试和查看文档,发现在python3中,同一进程内部,hash出来的值才是一致的。
诉求
因为这种差异,导致升级python3之后,使用hash函数不能和python2一致,导致无法兼容,所以需要在python3中想办法兼容python2
查看cpython源码
cpython相关源码地址(python2.7)
关键代码片段
cpython的代码在这里就不做解释了,感兴趣的可以自己去研究cpython源码。
最终python实现代码
将cpython的代码翻译过来,就是我们的python代码了,具体代码如下:
import ctypes
def python2_str_hash(origin_str: str) -> int:
# 使用ctypes.c_long的原因是在python3中没有了long型,都是使用的int,而python中的int是没有长度限制的。
x = ctypes.c_long(ord(origin_str[0]) << 7)
for i in origin_str:
x = ctypes.c_long((1000003*x.value) ^ ord(i))
x = x.value ^ len(origin_str)
return x
if __name__ == "__main__":
import sys
if len(sys.argv) != 2:
print("invalid input")
print(python2_str_hash(sys.argv[1]))
测试结果