2015-07-01 71 views
1

python的hash函數是否可移植?python的hash()是否便攜?

「便攜」我的意思是,它會在Python版本,平臺和實現中返回相同的結果(對於相同的數據)嗎?

如果沒有,是否有任何替代它提供這樣的功能(雖然仍然能夠散列公共數據結構)?


The documentation不是特別有用。 This question引用了一個似乎要推出自己版本的庫,但我不確定不可移植性是否會成爲它的原因。

+0

'hash'只是用於'dict'類型,它被實現爲一個哈希表。您可能需要標準庫中'hashlib'模塊的函數。 – chepner

+0

@chepner我正在尋找散列任意數據結構的東西,比如'hash',我不認爲'hashlib'那麼做? – goncalopp

+0

'hash'也不能散列任意數據結構。 (嘗試將'dict'或'set'傳遞給'hash'。) – chepner

回答

2

不,hash()不保證是便攜式。

默認情況下,Python 3.3還使用散列隨機數,其中某些類型在啓動時採用散列種子進行散列。 Python解釋器調用之間的哈希值不同。

object.__hash__() documenation

缺省情況下,STR,字節和datetime對象的__hash__()值「鹹」與不可預測的隨機值。雖然它們在單獨的Python過程中保持不變,但在重複調用Python之間它們是不可預測的。

這是爲了防止由精心挑選的輸入引起的拒絕服務,這些輸入利用了dict插入的最壞情況性能,O(n^2)複雜度。有關詳細信息,請參見http://www.ocert.org/advisories/ocert-2011-003.html

更改散列值會影響字典,集合和其他映射的迭代順序。 Python從來沒有對這個順序做過保證(它通常在32位和64位版本之間變化)。請參閱PYTHONHASHSEED

Python 2.6.8和3.2.3及更高版本支持相同的功能,但通常禁用它。

Python 3.2引入了一個sys.hash_info named tuple,它爲您提供了有關當前解釋器的哈希實現的詳細信息。

如果你需要一個可移植的散列,有很多的實現。標準庫包含稱爲hashlib的加密哈希庫;這些實現絕對是可移植的。另一種選擇是mm3 package,其提供Murmur3 non-cryptographic hash function implementations

常見的數據結構需要首先轉換爲字節;你可以使用序列化,如jsonpickle模塊。

+0

這對於主要問題是一個很好的迴應。至於替代方案,我[挖了一點](http://stackoverflow.com/questions/5417949/computing-an-md5-hash-of-a-data-structure),它看起來像序列化JSON是一個合理的選擇。如果你不介意我編輯你的答案,我可以包括這些信息 – goncalopp

+0

@goncalopp:序列化爲JSON不會給你一個緊湊的散列;你仍然需要通過某種哈希算法來運行它。我已經添加了一個指向'hashlib'的指針。 –

+0

是的,你可以通過hashlib運行它,如[這個答案](http://stackoverflow.com/a/10288255/1595865)。注意我已經編輯了這個問題,以澄清我正在尋找一些散列數據結構的東西,而不僅僅是字符串 – goncalopp