python中的确定性递归哈希

python中的确定性递归哈希,python,hash,Python,Hash,Python3的默认散列函数不是确定性的(散列(None)因运行而异),甚至没有尽最大努力以高概率生成唯一id(散列(-1)=散列(-2)为真) 是否还有其他一些哈希函数可以用作校验和(即两个数据结构散列到相同值的概率可以忽略不计,并且每次运行python都返回相同的结果),并且支持python的所有内置数据类型,包括None 理想情况下,它应该在标准库中。我可以对对象进行pickle处理或获取字符串表示,但这似乎不必要,而且浮点数的字符串表示可能是非常糟糕的校验和 我在标准库中找到了加密哈希(

Python3的默认散列函数不是确定性的(散列(None)因运行而异),甚至没有尽最大努力以高概率生成唯一id(散列(-1)=散列(-2)为真)

是否还有其他一些哈希函数可以用作校验和(即两个数据结构散列到相同值的概率可以忽略不计,并且每次运行python都返回相同的结果),并且支持python的所有内置数据类型,包括None

理想情况下,它应该在标准库中。我可以对对象进行pickle处理或获取字符串表示,但这似乎不必要,而且浮点数的字符串表示可能是非常糟糕的校验和

我在标准库中找到了加密哈希(md5、sha256),但它们只对ByTestRing进行操作

Haskell似乎在他们的标准库中几乎正确地理解了这一点。。。但是“Nothing::Maybe Int”和0都是散列到0的,所以在那里也不是完美的。

您可以使用对象上的任何散列。

您可以将排序键
json
hashlib
一起使用

hashlib.md5(json.dumps(data, sort_keys=True)).hexdigest()
根据安德烈瓦格纳的评论,摘自:


顺便提一下,由于这会导致安全漏洞,因此仅供参考。环境变量可用于在整个应用程序中禁用散列的随机化。

在Python 2中,散列是确定性的。它是为了在使用许多已知哈希冲突(例如对服务器)进行安全攻击后引入一些随机因素,作为拒绝服务攻击。看,嗯。
hash(-1)
成为
-2
真的很奇怪。从-100000000到100000000,这是散列值与自身不同的唯一整数。奇怪的我想知道他们是怎么做的。@StefanPochmann在CPython源代码中,返回
-1
是为错误保留的,因此
-1
被转换为
-2
以返回散列。@Artyer是的,我刚刚找到了@Stefan,谢谢你找到了原因。破坏哈希听起来很傻,但我不熟悉cPython代码。在C级,哈希应该使用函数参数而不是返回值来返回结果。至少他们没有把这个逻辑应用到数学函数上!谢谢我试试看。pickle是数据结构的纯函数吗?还是粘贴python版本字符串、时间戳等。。。在序列化数据中,对于
hashlib.md5(pickle.dumps({0,8})).hexdigest()
hashlib.md5(pickle.dumps({8,0})).hexdigest()
,我得到了不同的结果。是的,我现在也测试了它。问题是pickle输出本身会因为散列随机化而改变。如果符合您的需要,您可以使用
json.dumps
;它支持dicts,但不支持set。@nitzpo您确定散列随机化是原因吗?这不应该只适用于Python脚本的不同运行吗?即使我在一个表达式中执行它们,我也会得到不同:
pickle.dumps({0,8})==pickle.dumps({8,0})
给了我
False