2013-10-25 10 views
12

私は文字列をハッシュする必要があります。それはテキストファイルの隠れたフレーズにすぎないので、安全である必要はありません(人間の目には分かりません)。Pythonの文字列のハッシュ(隠蔽)

ユーザーが文字列を入力するときにハッシュし、既にハッシュしたもの(テキストファイルから)と比較するので、ランダムな文字列であってはいけません。

この目的にはどのような効果がありますか?組み込みのクラスでこれを行うことはできますか?

+1

**実際の**問題は何ですか?多くのハッシュアルゴリズムがありますが、bsetのアプローチは、どのようにハッシュ文字列を使用するかによって異なります。 –

答えて

32

まず、一意の結果を保証することはできません。ユニバース内のすべての文字列に対して一意の結果が必要な場合は、文字列自体(または圧縮されたバージョン)の保存をお勧めします。

その他の情報は1秒後です。最初にいくつかのハッシュを作ってみましょう。

あなたはいくつかの手順で文字列をハッシュする主な暗号化ハッシュのいずれかを使用することができ

hashlib方法:あなたがSHA1、SHA224、SHA256、SHA384、SHA512間の選択肢を持って

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

、そしてMD5については、組み込みのものが関係しています。

これらのハッシュアルゴリズムの違いは何ですか?

可変長のデータを取り、固定長のデータに変換することで、ハッシュ関数が機能します。

hashlibに組み込まれた各SHAアルゴリズムの固定長さは、名前に指定されたビット数です(sha1は160ビットです)。 2つの文字列が同じバケット(同じハッシュ値)に終わらないようにしたい場合は、より大きいダイジェスト(固定長)を持つハッシュを選択します。

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()は実行間でランダム化されています。 1回の実行では動作しますが、ほとんどの場合、あなたのプログラムの実行中には動作しません(あなたが言及したテキストファイルから取り込みます)。

なぜhash()がそのように構築されるのですか?さて、組み込みのハッシュはある特定の理由のためにそこにあります。ハッシュテーブル/辞書/メモリ内のルックアップテーブル暗号の使用ではなく、実行時の安価なルックアップ用です。

hash()を使用しないでください。hashlibを使用してください。

+4

'hash()'は実行間でランダム化されていますPython3.3 ie。プログラムの1回の実行で同じ値を返すだけに頼ることができます –

+0

素晴らしいです。 @gnibblerをありがとう、私はそれが実行の間に安定していないことを知らなかった。 –

+2

この投稿は素晴らしいです。必要なすべての情報が含まれています。あなたのような人々は岩、おかげで仲間。 – Lucas

0

単に例えば、hash()組み込み関数を使用します。

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

これは、各文字列に固有の数字を生成する予定ですか?デコードできますか(好奇心旺盛です)? – Lucas

+2

@ルーカス、固定サイズのハッシュ関数がすべての可能な文字列に対して異なる値を返すことは不可能です。例えば、ハッシュ関数が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で実行することはOKです(詳細はこちら)(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' 

長い文字列の16進数は「ハッシュ」です。 SHA-1は「強力な」ハッシュ関数です。同じ値にハッシュする2つの文字列を見つけたら有名になります;-)そして同じ入力が与えられれば、Pythonのすべてのリリースと実装におけるすべてのプラットフォームで同じ "hexdigest"を返します。

+1

特に、実行時にPython3.3の 'hash(somestring)'が異なるため、 –