无需重新计算即可获取字典键哈希值

2024-04-20 02:14:05 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法从字典中提取现有的密钥哈希值,而不需要重新计算它们?在

暴露它们并自愿地通过散列而不是键访问dict的风险是什么?在


Tags: 字典密钥dict风险办法自愿地
2条回答

我不认为Python的dictionary对象有任何公共API,可以让您看到它们的对象存储在一起的散列。在Python代码中,不能通过散列直接存储对象(可以在CPython中调用内部C函数)。有几个很好的理由说明不能通过哈希值而不是按键向字典中添加值。在

最明显的是多个键对象可能具有相同的哈希。如果发生这种哈希冲突,第二个值将插入哈希表中的其他位置。重要的是,它不会覆盖先前存储在哈希相同的键下的值。如果只传递散列而不传递密钥,Python将无法判断您是否使用同一个密钥,或者您提供的新密钥碰巧具有冲突哈希。在

不能通过散列插入的第二个原因是,这将是一个安全漏洞。当哈希冲突很少时,类似Python字典的哈希表的性能非常好。但是如果每个哈希值都相同,那就很糟糕了。如果您可以向Python程序提交所有哈希值都相同的数据,则可以执行非常高效的拒绝服务攻击(在Python的最新版本中添加了字符串的新散列随机化,使这种攻击更加困难)。在

Python dict的键必须是hashable,即实现__hash__特殊方法(以及与您的问题无关的其他方法),或者是一些预先确定的内置类型之一。所以你实际上可以在没有表的情况下访问一个键的散列值,例如,通过

>>> '123'.__hash__()
163512108404620371

或者更均匀

^{pr2}$

尽管如此,正如评论所指出的,散列值和表中的位置不是一回事。事实上,随着表大小的调整,键的哈希值将保持不变,但位置可能会改变。因此,作为:

  • 通过hash()

  • 该位置将暴露字典的内部状态

  • __hash__方法中,可以很容易地在对象中“缓存”哈希值

暴露钥匙的位置可能没有意义。在

相关问题 更多 >