python3 兼容python2 的hash函数

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]))

测试结果

原文地址:https://www.cnblogs.com/yuzhenjie/p/14282999.html