home changes contents help options

069:メッセージダイジェストを作成する

hashlib モジュール

Python 2.5 より追加されました hashlib モジュールを使います。 Python 2.4 まで md5 , sha モジュールとして実装されていたものを 統合、そして対応アルゴリズムを追加したものです。使い方は変わっていません。 hashlib モジュールで対応しているハッシュアルゴリズムは md5, sha1, sha224, sha256, sha384, および sha512 です。 Python 2.4 以前を用いる場合は md5 , sha モジュールを用いてください。

使い方は以下の通りです。 まずハッシュ値オブジェクトを作り(例は md5 )、 update メソッドにハッシュ値計算対象となるデータを文字列型で与えます。 ハッシュ値(ダイジェスト)は digest メソッドで得られます。 16 進ダンプしたハッシュ値(ダイジェスト)は hexdigest メソッドで得られます。:

   >>> import hashlib
   >>> md5object = hashlib.md5()
   >>> md5object.update("python_recipe")
   >>> md5object.digest()
   '\x9d\xe7\xe2\xe3\xbf7/\x98\x00\xad\xf0\xc3\x08\x0e<\n'
   >>> md5object.hexdigest()
   '9de7e2e3bf372f9800adf0c3080e3c0a'

ハッシュ値オブジェクトを作る際に引数にデータを渡しておくことができます。 こうすることで update メソッドを呼ぶ手間を省けます。:

   >>> x = hashlib.md5("python_recipe")
   >>> x.hexdigest()
   '9de7e2e3bf372f9800adf0c3080e3c0a'

update というメソッド名からデータを次々に渡してハッシュ値を更新できそうであることがうかがえます。 事実、可能です。巨大なデータのハッシュ値を計算したいがすべてをメモリに置くことなどできない、 といった問題を解決します。 次のコードはあるデータに対し、 md5 ハッシュ値を一度に算出したものと、 1024 バイトずつ読んで逐次更新した結果を出力しています。:

   >>> import StringIO
   >>> s = "python_recipe" * 1000
   >>> sio = StringIO.StringIO(s)
   >>> md5_1 = hashlib.md5(s)
   >>> md5_2 = hashlib.md5()
   >>> while True:
   ...     data = sio.read(1024)
   ...     if data:
   ...         md5_2.update(data)
   ...     else:
   ...         break
   ...
   >>> md5_1.hexdigest()
   'eb3e7afb210e2b281ea963ce95fe8437'
   >>> md5_2.hexdigest()
   'eb3e7afb210e2b281ea963ce95fe8437'

おまけ

ハッシュ値オブジェクトのメソッド

ハッシュ値オブジェクトはもう 1 つだけメソッドをもっています。 copy メソッドです。 引数なしで呼出します。自身を複製したものを返します。

もう1つのアルゴリズム

どうやら OpenSSL? ライブラリが用いるための アルゴリズムがあるようです。これは hashlib.new("ripemd160") で使えます。

md5 モジュール

md5 アルゴリズムにのみ対応しています。 これを用いる場合 md5.new() もしくは md5.md5() でハッシュオブジェクトを得ます。

sha モジュール

sha1 アルゴリズムにのみ対応しています。 これを用いる場合 sha.new() でハッシュオブジェクトを得ます。 リファレンスマニュアルには記述がありませんが sha.sha() でも得られました。 sha.new == sha.sha で True が返ってくるので、 sha は new の別名です。