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

2025-01-07 08:44:00
admin
原创
132
摘要:问题描述:我在 python 3.3 中实现了 BloomFilter,每次会话都会得到不同的结果。深入研究这种奇怪的行为让我找到了内部 hash() 函数 - 它每次会话都会为同一字符串返回不同的哈希值。例子:>>> hash("235") -3105695350152...

问题描述:

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

例子:

>>> hash("235")
-310569535015251310

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

>>> hash("235")
-1900164331622581997

为什么会发生这种情况?这有什么用?


解决方案 1:

Python 使用随机哈希种子来防止攻击者通过向您发送旨在发生冲突的密钥来对您的应用程序进行 tar-pitting。请参阅原始漏洞披露。通过使用随机种子(在启动时设置一次)抵消哈希,攻击者无法再预测哪些密钥会发生冲突。

PYTHONHASHSEED您可以通过设置环境变量来设置固定种子或禁用该功能;默认值是,random但您可以将其设置为固定正整数值,并0完全禁用该功能。

Python 2.7 和 3.2 版本默认禁用该功能(使用开关-R或设置PYTHONHASHSEED=random来启用它);它在 Python 3.3 及更高版本中默认启用。

如果您依赖 Python 集合中键的顺序,则不要这样做。Python 使用哈希表来实现这些类型,并且它们的顺序取决于插入和删除历史记录以及随机哈希种子。请注意,在 Python 3.5 及更早版本中,这也适用于字典。

另请参阅object.__hash__()特殊方法文档:

注意:默认情况下,__hash__()str、bytes 和 datetime 对象的值会使用不可预测的随机值进行“加盐”。虽然它们在单个 Python 进程中保持不变,但在重复调用 Python 时,它们不可预测。

这是为了防止因精心选择的输入而导致的拒绝服务,这些输入会利用字典插入的最坏情况性能,即 O(n^2) 复杂度。有关详细信息,请参阅http://www.ocert.org/advisories/ocert-2011-003.html

更改哈希值会影响字典、集合和其他映射的迭代顺序。Python 从未对此顺序做出保证(并且通常在 32 位和 64 位版本之间有所不同)。

另请参阅PYTHONHASHSEED

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

由于偏移量由前缀和后缀(分别为起始值和最终异或值)组成,因此很遗憾,您不能只存储偏移量。从好的方面来说,这确实意味着攻击者也无法通过计时攻击轻松确定偏移量。

解决方案 2:

hash()当我尝试比较会话之间数据库中保存的记录时,这种行为让我陷入困境。

解决方案PYTHONHASHSEED太复杂了,因为我需要我的程序可靠地工作,而不依赖于环境变量设置。

因此我创建了一个简单的 has 函数来哈希字符串(将任何内容转换为字符串都很容易),并生成一个 32 位正整数作为哈希值。这不是一个加密安全的哈希值,但对于快速比较来说已经足够了。

def myHash(text:str):
  hash=0
  for ch in text:
    hash = ( hash*281  ^ ord(ch)*997) & 0xFFFFFFFF
  return hash

乘法中的数字只是为了混合位而任意选择的素数。

如果您希望哈希值为十六进制字符串,则可以将最后一行替换为:

return hex(hash)[2:].upper().zfill(8)

解决方案 3:

在 Python 3 中,哈希随机化默认处于启用状态。这是一项安全功能:

哈希随机化旨在提供保护,防止因精心选择的输入而导致的拒绝服务,这些输入会利用字典构造的最坏情况性能

在 2.6.8 之前的版本中,您可以使用 -R 或PYTHONHASHSEED环境选项在命令行中打开它。

PYTHONHASHSEED您可以通过设置为零来将其关闭。

解决方案 4:

如果您需要从哈希函数获得确定性值,则可以使用以下哈希函数hashlib

import hashlib

hash_obj = hashlib.sha256(b"hello")
hex_hash = hash_obj.hexdigest()
print(hex_hash)
# Always prints: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

模块中有多种可用的哈希函数,更多信息请参阅hashlib 文档。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2941  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1803  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   31  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   31  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   28  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用