2014-02-13 87 views
2

所以,这很有趣 - Python的hash臭名昭着地返回Truehash(-1) == hash(-2),as discussed elsewhere,但这又如何呢?hash((-2,2))== hash((2,-2))返回True(Python)

>>> hash((-2,2)) == hash((2,-2)) 
True 

这是一个功能

其他一些快速的实验:

>>>(-2,2) == (2,-2) 
False 
>>>hash((-1,)) == hash((-2,)) 
True 
>>>hash((-1,-2)) == hash((-2,-1)) 
True 
>>>hash((-2.01,2.01)) == hash((2.01,-2.01)) 
False 
>>>hash((-1,1)) == hash((1,-1)) 
False 
+1

那会是什么样的功能?我倾向于说它显然不是一个功能,因为你希望你的散列函数不具有这些属性。你的问题是什么? –

+1

顺便说一句,你可能打算编写'(-1,)',因为额外的一对parens是多余的,否则 –

+0

好吧,'hash(-1)== hash(-2)'是一个特征,这不是一个错误,并有一个原因就是这样(上面的链接)。这是否有类似的解释 - 还是仅仅是一种怪异?这是我的问题。 –

回答

1

在看哈希逻辑之前,让我们看一些小技巧。

  1. python整数的散列值将是数字本身。

  2. 只有第1点的例外是-1。因为-1在内部用于指示错误情况。所以,散列值-1将是-2。 (对于-2也,这将是-2只)。

有了这样的认识,我们可以回答你的例子2,3和5

例2:的哈希值-1 ==哈希值为-2。所以,这是真的。

实施例3:同实施例2

实施例5的原因:-1哈希值和1(分别为2和1)是不同的。这就是为什么结果是False

这种情况下,例4,浮点数的散列值与数字本身不一样,因为散列值应该是整数。这些数字没有被表示,因为它们在内存中。 (2.01不作为2.01存储在内存中)。所以,他们的哈希值是不同的是可以接受的。

要回答示例1,让我们看看一些代码。由于每tuple hashing implementation,让使用Python程序计算哈希值

x, hash_mult = int("0x345678", 16), 1000003 
x, hash_mult = (x^2) * hash_mult, hash_mult + 82522 
x = (x^-2) * hash_mult 
print(x + 97531)         # -3713082714466793269 

x, hash_mult = int("0x345678", 16), 1000003 
x, hash_mult = (x^-2) * hash_mult, hash_mult + 82522 
x = (x^2) * hash_mult 
print(x + 97531)         # -3713082714466793269 

print(hash((-2, 2)))        # -3713082714466793269 

注:这一点不仅适用于-2, 2,它是所有整数正确的,除了上面看的情况下和所有的倍数8.

3

这不是一个特征;这是巧合。哈希碰撞发生。

Python的整数哈希真的很笨,它的元组哈希通常没问题。

Python的字典实施是为了踢严重的对接与坏散列,所以没关系太多。

+2

巧合的是,我实际上只是查找了本周早些时候Python做元组哈希的方式,因为我正在考虑为JSON数据编写一个独立于实现的/独立于语言的散列。我发现它有点有趣:http://hg.python.org/cpython/file/6e04027ed53e/Objects/tupleobject.c#l341 –

+0

正确 - 源代码... –