【问题标题】:Deterministic, recursive hashing in pythonpython中的确定性递归哈希
【发布时间】:2017-12-14 08:57:06
【问题描述】:

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

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

理想情况下它会在标准库中。我可以腌制对象或获取字符串表示形式,但这似乎不必要地hacky,并且浮点数的字符串表示形式可能是非常糟糕的校验和。

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

Haskell 似乎在他们的标准库中得到了这个〜几乎是正确的......但是“Nothing::Maybe Int”和 0 都哈希为 0,所以它在那里也不完美。

【问题讨论】:

  • 在 Python 2 中,散列是确定性的。它被用来在使用许多已知的哈希冲突的安全漏洞之后引入一些随机因素,例如对服务器,作为拒绝服务攻击。见here
  • 嗯。 hash(-1) 成为 -2 真的很奇怪。从 -100,000,000 到 100,000,000,这是唯一一个哈希值与自身不同的 int。诡异的。我想知道他们是如何/为什么这样做的。
  • @StefanPochmann 在 CPython 源代码中,返回 -1 是为错误保留的,因此 -1 转换为 -2 以返回哈希。
  • @Artyer 是的,我刚找到stackoverflow.com/questions/10130454/…
  • @Stefan,感谢您找到原因。打破哈希听起来很傻,但我不熟悉 cPython 代码。似乎在 C 级别,哈希应该使用函数参数而不是返回值来返回结果。至少他们没有将这个逻辑应用于数学函数!

标签: python hash


【解决方案1】:

您可以在 pickled 对象上使用来自 hashlib 的任何哈希。 pickle.dumps not suitable for hashing.

您可以使用排序键jsonhashlib

hashlib.md5(json.dumps(data, sort_keys=True)).hexdigest()

取自:https://stackoverflow.com/a/10288255/3858507,根据 AndrewWagner 的评论。

顺便说一下,仅供参考,因为这会导致安全漏洞PYTHONHASHSEED 环境变量可用于禁用整个应用程序中的哈希随机化。

【讨论】:

  • 谢谢!我会尝试一下。 pickle 是数据结构的纯函数吗?还是在序列化数据中粘贴 python 版本字符串、时间戳等?
  • hashlib.md5(pickle.dumps({0, 8})).hexdigest()hashlib.md5(pickle.dumps({8, 0})).hexdigest() 得到不同的结果。
  • 是的,我现在也测试过了。问题是由于散列随机化,泡菜输出本身会发生变化。如果适合您的需要,您可以使用json.dumps;它支持字典但不支持集合。
  • @nitzpo 你确定哈希随机化是原因吗?这不应该只适用于 Python 脚本的不同运行吗?即使我在一个表达式中执行它们,我也会有所不同:pickle.dumps({0, 8}) == pickle.dumps({8, 0}) 给了我False
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 2016-07-11
  • 2013-08-09
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多