Python 使用随机哈希种子来防止攻击者通过向您发送旨在冲突的密钥来对您的应用程序进行 tar-pit。请参阅原始漏洞披露 http://www.ocert.org/advisories/ocert-2011-003.html。通过使用随机种子(在启动时设置一次)抵消哈希值,攻击者无法再预测哪些密钥将发生冲突。
您可以通过设置固定种子或禁用该功能PYTHONHASHSEED环境变量 https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED;默认是random
但您可以将其设置为固定的正整数值,使用0
完全禁用该功能。
Python 2.7 和 3.2 版本默认禁用该功能(使用-R
开关或设置PYTHONHASHSEED=random
启用它);它在 Python 3.3 及更高版本中默认启用。
如果您依赖 Python 集中键的顺序,那么就不要这样做。 Python 使用哈希表来实现这些类型及其顺序取决于插入和删除历史记录 https://stackoverflow.com/questions/15479928/why-is-the-order-in-python-dictionaries-and-sets-arbitrary/15479974#15479974以及随机哈希种子。请注意,在 Python 3.5 及更早版本中,这也适用于字典。
另请参阅object.__hash__()特殊方法文档 https://docs.python.org/3/reference/datamodel.html#object.__hash__:
Note:默认情况下,__hash__()
str、bytes 和 datetime 对象的值使用不可预测的随机值“加盐”。尽管它们在单个 Python 进程中保持不变,但在 Python 的重复调用之间它们是不可预测的。
这样做的目的是为了防止由于精心选择的输入而导致拒绝服务,这些输入利用了字典插入的最坏情况性能,复杂度为 O(n^2)。看http://www.ocert.org/advisories/ocert-2011-003.html http://www.ocert.org/advisories/ocert-2011-003.html了解详情。
更改哈希值会影响字典、集合和其他映射的迭代顺序。 Python 从未对这种顺序做出保证(并且它通常在 32 位和 64 位版本之间有所不同)。
也可以看看PYTHONHASHSEED
.
如果您需要稳定的哈希实现,您可能想看看hashlib module https://docs.python.org/3/library/hashlib.html;这实现了加密哈希函数。这pybloom 项目使用这种方法 https://github.com/jaybaird/python-bloomfilter/blob/master/pybloom/pybloom.py#L54-L98.
不幸的是,由于偏移量由前缀和后缀(分别是起始值和最终异或值)组成,因此您不能只存储偏移量。从好的方面来说,这确实意味着攻击者也无法通过定时攻击轻松确定偏移量。