hashlib – 暗号ハッシュとメッセージダイジェスト

目的:暗号ハッシュとメッセージダイジェスト
利用できるバージョン:2.5

hashlib モジュールは独立した md5sha モジュールを廃止して、一貫した API を提供します。特定のハッシュアルゴリズムと連携するには、ハッシュオブジェクトを作成する適切なコンストラクタ関数を使用してください。その後は、どのアルゴリズムが使用されても同じ API でハッシュと対話的にやり取りできます。

hashlib は内部で OpenSSL を使用するので OpenSSL が提供する次のような全てのアルゴリズムが利用可能です。

  • md5
  • sha1
  • sha224
  • sha256
  • sha384
  • sha512

サンプルデータ

全てのサンプルは次のサンプルデータを使用します。

import hashlib

lorem = '''Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.'''

MD5 サンプル

あるデータブロック(ここでは ASCII 文字列)の MD5 ダイジェストを算出するには、ハッシュオブジェクトを作成して、そのデータを追加して、そのダイジェストを計算します。

import hashlib

from hashlib_data import lorem

h = hashlib.md5()
h.update(lorem)
print h.hexdigest()

このサンプルは digest() の代わりに hexdigest() メソッドを使用します。その理由はその出力が表示できるように整形されるからです。もしバイナリダイジェストが許容されるなら digest() を使用できます。

$ python hashlib_md5.py
c3abe541f361b1bfbbcfecbf53aad1fb

SHA1 サンプル

同じデータの SAH1 ダイジェストはほとんど同じ方法で計算されます。

import hashlib

from hashlib_data import lorem

h = hashlib.sha1()
h.update(lorem)
print h.hexdigest()

アルゴリズムを MD5 から SHA1 に変更したので、このサンプルのダイジェストの値は違っています。

$ python hashlib_sha1.py
ac2a96a4237886637d5352d606d7a7b6d7ad2f29

new()

コンストラクタ関数を直接使用するよりも名前でアルゴリズムを参照する方が便利なときがあります。例えば、設定ファイルにハッシュの種別を保存できると便利です。そういった場合は、ハッシュ算出機を作成するために new() を使用してください。

import hashlib
import sys


try:
    hash_name = sys.argv[1]
except IndexError:
    print 'Specify the hash name as the first argument.'
else:
    try:
        data = sys.argv[2]
    except IndexError:    
        from hashlib_data import lorem as data
    
    h = hashlib.new(hash_name)
    h.update(data)
    print h.hexdigest()

様々な引数で実行します。

$ python hashlib_new.py sha1
ac2a96a4237886637d5352d606d7a7b6d7ad2f29

$ python hashlib_new.py sha256
88b7404fc192fcdb9bb1dba1ad118aa1ccd580e9faa110d12b4d63988cf20332

$ python hashlib_new.py sha512
f58c6935ef9d5a94d296207ee4a7d9bba411539d8677482b7e9d60e4b7137f68d25f9747cab62fe752ec5ed1e5b2fa4cdbc8c9203267f995a5d17e4408dccdb4

$ python hashlib_new.py md5
c3abe541f361b1bfbbcfecbf53aad1fb

1度以上 update() を呼び出す

ハッシュ計算機の update() メソッドは何度も呼び出すことができます。毎回、テキストを追加して与えることでダイジェストを更新します。例えば、これはメモリにファイル全体を読み込むよりもずっと効率的です。

import hashlib

from hashlib_data import lorem

h = hashlib.md5()
h.update(lorem)
all_at_once = h.hexdigest()

def chunkize(size, text):
    "Return parts of the text in size-based increments."
    start = 0
    while start < len(text):
        chunk = text[start:start+size]
        yield chunk
        start += size
    return

h = hashlib.md5()
for chunk in chunkize(64, lorem):
    h.update(chunk)
line_by_line = h.hexdigest()

print 'All at once :', all_at_once
print 'Line by line:', line_by_line
print 'Same        :', (all_at_once == line_by_line)

このサンプルはサイズの小さいテキストを処理するので少し不自然な気がします。しかし、データが読み込まれる、もしくは別の方法で生成されるようにダイジェストを徐々に更新する方法を説明します。

$ python hashlib_update.py
All at once : c3abe541f361b1bfbbcfecbf53aad1fb
Line by line: c3abe541f361b1bfbbcfecbf53aad1fb
Same        : True

See also

hashlib
本モジュールの標準ライブラリドキュメント
Voidspace: IronPython and hashlib
IronPython で動作する hashlib のラッパー
hmac
hmac モジュール
Bookmark and Share