2014-02-13 51 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

正確 - 源代碼... –