获取字典键哈希而无需重新计算

时间:2016-04-01 19:44:40

标签: python dictionary hash

有没有办法从字典中提取现有的键哈希值,而无需再次重新计算它们?

暴露它们并且通过哈希而不是钥匙访问字典会有什么风险?

2 个答案:

答案 0 :(得分:2)

我不认为Python的字典对象有任何公共API,允许您查看其对象存储的哈希值。您不能通过Python代码中的哈希直接存储对象(可以通过在CPython中调用内部C函数)。有一些很好的理由是您无法通过哈希值而不是按键将值添加到字典中。

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

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

答案 1 :(得分:2)

Python dict的密钥必须是hashable,即实现__hash__特殊方法(以及与您的问题无关的其他一些方法),或者是其中之一预定的内置类型。因此,您实际上可以在没有表格的情况下访问密钥的哈希值,例如通过

>>> '123'.__hash__()
163512108404620371

或更统一

>>> hash('123')
163512108404620371
>>> hash(2)
2

话虽如此,正如评论所指出的,哈希值和表中的位置并不是一回事。实际上,当表调整大小时,键的哈希值将保持不变,但位置可能会更改。因此,如:

  • 您可以通过hash()

  • 轻松获取哈希值
  • 该职位将公开字典的内部状态

  • 您可以在__hash__方法

  • 中轻松“缓存”对象中的哈希值

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