Python的字典映射使用什么哈希算法?

Joe*_*ett 30 python hashmap

我正忙着制作一个命令行解析器,并想知道什么样的哈希算法python dict的使用?

我设置它的方式,我有一个模式匹配算法,它将标记化的输入序列与字典键匹配.一些键相对较长(长度为5或6个6-7个字符串的元组).我想知道长字典键是否会显着降低密钥检索的效率.

Ian*_*and 33

它使用的散列取决于被用作键的对象 - 每个类可以定义自己的__hash __()方法,并且它为特定实例返回的值是用于字典的值.

Python本身为str和tuple类型提供了哈希实现.快速查看源代码应该揭示这些的确切算法.

元组的散列基于其内容的散列.该算法基本上是这个(略有简化):

def hash(tuple):
    mult = 1000003
    x = 0x345678
    for index, item in enumerate(tuple):
        x = ((x ^ hash(item)) * mult) & (1<<32)
        mult += (82520 + (len(tuple)-index)*2)
    return x + 97531
Run Code Online (Sandbox Code Playgroud)

对于字符串,解释器还迭代每个字符,将它们与此(再次,略微简化)算法组合:

def hash(string):
    x = string[0] << 7
    for chr in string[1:]:
        x = ((1000003 * x) ^ chr) & (1<<32)
    return x
Run Code Online (Sandbox Code Playgroud)

需要担心的一个更大问题是避免哈希冲突.当字典试图找到存储新对象的位置时,碰撞散列键将导致线性搜索(现在这被认为是一个安全问题,并且在即将发布的python版本中行为可能会发生变化)

  • 如果攻击者可以控制字典中使用的键,那么他们可能能够插入成百上千个相互冲突的键,从而使插入操作变得非常缓慢。在某些情况下,这可能导致机器无响应,或数据库无法使用——Dos 攻击 (5认同)
  • @Joel Cornett:这是一个安全问题,因为哈希表使用存储桶来存储密钥,具有相同哈希码的密钥将被散列到同一个存储桶,迫使哈希表在每次搜索密钥时进行线性搜索,如果密钥的数量很大,这可能是非常低效的(甚至可能导致拒绝服务).如果程序遇到具有散列到相同散列码的不同键的散列表,则可能导致拒绝服务攻击. (3认同)
  • 哦好的。出于某种原因,我假设 python 只是对所有数据类型使用通用字节码哈希算法。就冲突的哈希键而言,我认为这不会成为问题,因为我将拥有的键的数量(相对)很小 - 可能有数千个。请原谅我的无知,但是冲突的哈希值和线性搜索如何成为安全问题呢? (2认同)
  • 我听到讨论的第一个攻击场景是针对 Web 服务——如果 POST 变量最终出现在以它们的名字为键的字典中,那么攻击者就可以完全控制这些键,并且可以任意降低服务器的速度,并使用足够多的变量。不过,我不知道在野外是否有这样的攻击。 (2认同)