python教程—Python 3.3中的哈希函数在会话之间返回不同的结果-Python实用宝典

python教程—Python 3.3中的哈希函数在会话之间返回不同的结果

我在python 3.3中实现了一个BloomFilter,每次会话都会得到不同的结果。深入研究这种奇怪的行为使我找到了内部hash()函数——它在每个会话中为相同的字符串返回不同的hash值。

我在python 3.3中实现了一个BloomFilter,每次会话都会得到不同的结果。深入研究这种奇怪的行为使我找到了内部hash()函数——它在每个会话中为相同的字符串返回不同的hash值。

例子:

    >>> hash("235") -310569535015251310

——打开一个新的python控制台——

    >>> hash("235") -1900164331622581997

为什么会这样?
为什么这个有用?

回答

Python使用随机散列种子,通过发送设计为冲突的密钥来防止攻击者对应用程序进行tar-pitting。参见原始漏洞披露。通过使用随机种子(在启动时设置一次)抵消散列,攻击者不再能够预测哪些键将发生碰撞。

您可以通过设置PYTHONHASHSEED环境变量来设置固定种子或禁用该特性;默认值是random,但是您可以将其设置为一个固定的正整数,而0则完全禁用该特性。

Python版本2.7和3.2默认禁用了该特性(使用-R开关或设置PYTHONHASHSEED=random启用该特性);在Python 3.3及以上版本中,默认情况下是启用的。

如果您依赖于Python字典或set中的键的顺序,那么不要这样做。Python使用一个哈希表来实现这些类型,它们的顺序取决于插入和删除历史记录以及随机哈希种子。

还请参见object. _hash__()特殊方法文档:

Note: By default, the __hash__() values of str, bytes and datetime objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python.
This is intended to provide protection against a denial-of-service caused by carefully-chosen inputs that exploit the worst case performance of a dict insertion, O(n^2) complexity. See http://www.ocert.org/advisories/ocert-2011-003.html for details.
Changing hash values affects the iteration order of dicts, sets and other mappings. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).
See also PYTHONHASHSEED.

如果您需要一个稳定的散列实现,您可能需要查看hashlib模块;这实现了加密哈希函数。pybloom项目使用这种方法

不幸的是,由于偏移量由前缀和后缀(分别为起始值和最终的x值)组成,因此不能只存储偏移量。从好的方面来说,这也意味着攻击者不能轻易地确定与定时攻击的偏移量。

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
1

发表评论