hash()是如何计算元组的hash的


函数hash()如何计算元组的哈希值?例如:
t = (1,2,3)
print(hash(t))

给出输出

-378539185

如果您熟悉C编程和一些高级数学,您可以在C中检查此函数的实现。看起来,该算法对元组中的每个元素进行异或,并添加了一些魔力。

static Py_hash_t
tuplehash(PyTupleObject *v)
{
Py_uhash_t x;  /* Unsigned for defined overflow behavior. */
Py_hash_t y;
Py_ssize_t len = Py_SIZE(v);
PyObject **p;
Py_uhash_t mult = _PyHASH_MULTIPLIER;
x = 0x345678UL;
p = v->ob_item;
while (--len >= 0) {
y = PyObject_Hash(*p++);
if (y == -1)
return -1;
x = (x ^ y) * mult;
/* the cast might truncate len; that doesn't change hash stability */
mult += (Py_hash_t)(82520UL + len + len);
}
x += 97531UL;
if (x == (Py_uhash_t)-1)
x = -2;
return x;
}

请注意,这是CPython的当前实现。其他Python解释器甚至其他版本的CPython可能具有不同的哈希函数。这个名为SipHash的特殊实现自2013年以来一直在使用。有关详细说明,请参阅PEP 456——安全且可互换的哈希算法。

SipHash是一个加密伪随机函数,具有128位种子和64位输出。。。。SipHash是一系列伪随机函数(也称为密钥散列函数(,针对短消息的速度进行了优化。目标应用程序包括网络流量身份验证和防御散列泛滥DoS攻击。

标准库文档有一些细节。哈希函数通常具有以下属性:

  1. 如果两个值相等,则它们总是具有相同的哈希值;以及
  2. 如果两个值不同,那么它们可能具有不同的哈希值

有更简单、更难的编写方法,也有更快、更慢的方法,但重要的是,不同的值很少产生相同的哈希值。一个好的实现是很棘手的,但您通常并不十分关心实现。

(在Python中,您几乎不需要直接调用hash();如果它是用作键的自定义类型的字典实现的一部分,我也不会感到惊讶。Object.__hash__()文档说明了更多。(

最新更新