2013-10-25 90 views
12

我需要的是哈希一個字符串。它不一定非常安全,因爲它只是文本文件中的一個隱藏短語(它不需要人眼識別)。Python中的哈希(隱藏)字符串

它不應該只是一個隨機字符串,因爲當用戶鍵入字符串時,我想散列它並將其與已經散列的字符串(來自文本文件)進行比較。

什麼是最好的這個目的?它可以通過內置的類來完成嗎?

+1

什麼是你的**真正的**問題?有很多散列算法,bset方法取決於你如何使用散列字符串。 –

回答

32

首先,讓我說,你不能保證獨特的結果。如果你想要宇宙中所有字符串的獨特結果,你最好存儲字符串本身(或壓縮版本)。

更多關於這一點。我們先來看看哈希。

hashlib方式

你可以使用任何的主密碼哈希散列字符串有以下幾個步驟:

>>> import hashlib 
>>> sha = hashlib.sha1("I am a cat") 
>>> sha.hexdigest() 
'576f38148ae68c924070538b45a8ef0f73ed8710' 

你有SHA1,SHA224,SHA256,SHA384,SHA512之間進行選擇,和MD5就內置插件而言。

這些散列算法有什麼區別?

散列函數通過獲取可變長度的數據並將其轉換爲固定長度的數據來工作。

對於內置於hashlib中的每個SHA算法,固定長度是名稱中指定的位數(除了sha1爲160位)。如果你想更好地確定兩個字符串不會在同一個桶(相同的散列值)中結束,請選擇一個更大的摘要(固定長度)的散列。

在有序,這些都是消化大小必須一起工作:

Algorithm Digest Size (in bits) 
md5  128 
sha1  160 
sha224  224 
sha256  256 
sha384  384 
sha512  512 

越大消化不太可能你就會有一個碰撞,只要你的哈希函數值得其鹽。

等一下,hash()怎麼樣?

內置在hash()函數返回整數,這也可以很容易地用於您概述的目的。雖然有問題。

>>> hash('moo') 
6387157653034356308 
  1. 如果你的計劃是要在不同的系統上運行,你不能確保hash將返回同樣的事情。事實上,我正在使用64位Python在64位機器上運行。這些值將與32位Python大不相同。

  2. 對於Python 3.3+,如@gnibbler指出的,hash()是在運行之間隨機化的。它將用於單次運行,但幾乎肯定不會跨越程序的運行(從您提到的文本文件拉出)。

爲什麼hash()這樣構建?那麼,內置哈希是有一個特定的原因。哈希表/字典/查找內存中的表。不是用於加密,而是用於運行時廉價的查找。

請勿使用hash(),請使用hashlib

+4

'hash()'在運行之間隨機化Python3.3 ie。你只能依靠它在程序的一次運行中返回相同的值 –

+0

太好了。感謝那個@gnibbler,我不知道它在運行之間不穩定。 –

+2

這篇文章太棒了。包含我需要的所有信息。像你這樣的人非常感謝,夥計。 – Lucas

0

只需使用hash()內置的功能,例如:

s = 'a string' 
hash(s) 
=> -8411828025894108412 
+0

這是要爲每個字符串生成唯一的數字嗎?它可以解碼(只是好奇)? – Lucas

+2

@Lucas,固定大小的散列函數不可能爲所有可能的字符串返回不同的值。例如,如果散列函數返回2位,則它只有4個可能的值。 –

+0

@Tim Peters它可以解碼(只是好奇)? – Lucas

5

您可以簡單地使用的base64模塊來實現自己的目標:

>>> import base64 
>>> a = 'helloworld' 
>>> encoded_str = base64.encodestring(a) 
>>> encoded_str 
'aGVsbG93b3JsZA==' 
>>> base64.decodestring(encoded_str) 
'helloworld' 
>>> 

當然,你也可以使用的hashlib模塊,它更安全,因爲散列字符串不能(或非常非常難)被解碼,但是對於你的問題,base64就足夠了 - 「它並不一定非常安全」

+0

默認情況下,base64是否帶有Python2.3(是的,我知道它很奇怪)? – Lucas

+0

是的!可以在Python 2.3中運行上面的代碼[http://docs.python.org/release/2.3/lib/module-base64.html] – tinylambda

4

請注意,Python的字符串哈希不是「定義」的 - 它可以並且確實在不同版本和實現之間有所不同。因此存儲Python字符串散列會產生困難。 CPython的字符串散列也不會試圖變得「模糊」。

一個標準的方法是使用散列函數設計這種事情。像這樣:

>>> import hashlib 
>>> encoded = hashlib.sha1("abcdef") # "abcdef" is the password 
>>> encoded.hexdigest() 
'1f8ac10f23c5b5bc1167bda84b833e5c057a77d2' 

長的十六進制數字串是「散列」。 SHA-1是一個「強大」散列函數。如果你發現兩個字符串散列到相同的值,你可以名聲大噪;-)給定相同的輸入,它將在Python所有版本和實現的所有平臺上返回相同的「hexdigest」。

+1

尤其是因爲Python3.3'hash(somestring)'在運行時不同 –