ファイルが同一であるか調べるのに便利です。
使い方
バイナリデータを指定したハッシュアルゴリズムで計算し、バイナリのdigestや16進数のhexdigestで取り出すことができます。
簡単な例
hashib.アルゴリズム名 ( バイナリデータ ).hexdigest()
文字列'abc'のmd5を表示します。
>>> import hashlib
>>> hashlib.md5(b'abc').hexdigest()
'900150983cd24fb0d6963f7d28e17f72'
newを使った例
newを使うとアルゴリズムを変えて計算することもできます。
文字列'abc'をMD5とSHA-1で計算し出力します。
# モジュールをインポートします
import hashlib
# バイナリデータを用意します
BinaryData = b'abc'
for i in ('md5','sha1'):
# ハッシュオブジェクトを作ります
h = hashlib.new( i)
# バイナリデータからハッシュを計算します
h.update(BinaryData)
# ハッシュオブジェクトを16進数で出力します
print( i, h.hexdigest())
結果
md5 900150983cd24fb0d6963f7d28e17f72
sha1 a9993e364706816aba3e25717850c26c9cd0d89d
分割して計算する例
データサイズが大きすぎる場合はupdateを使います。
この例では分割して計算しても出力が同じになることを確認できます。
# モジュールをインポートします
import hashlib
# 大きなバイナリデータを用意します
BigBinaryData = b'abcd'*0x100000
# ハッシュアルゴリズムを決めます
algo = 'md5'
# 分割せずにハッシュを計算する
h = hashlib.new(algo)
h.update(BigBinaryData)
print(algo,h.hexdigest())
# ハッシュオブジェクトを作ります
h = hashlib.new(algo)
# 分割する長さをブロックサイズの整数倍に決めます
Length = hashlib.new(algo).block_size * 4096
# データがある間ループします
while BigBinaryData:
# 計算に使用する部分を取り出します
BinaryData = BigBinaryData[:Length]
# 取り出した部分を切り離して捨てます
BigBinaryData = BigBinaryData[Length:]
# ハッシュオブジェクトに追加して計算します。
h.update(BinaryData)
# ハッシュオブジェクトを16進数で出力します
print(algo,h.hexdigest())
結果
md5 cf3598e0d72fbed531070afd240c76b9
md5 cf3598e0d72fbed531070afd240c76b9
巨大なファイルのハッシュ
メモリに読み込めないほど巨大なファイルは分割して計算します。
# モジュールをインポートします
import hashlib
# ハッシュアルゴリズムを決めます
algo = 'md5'
# ハッシュオブジェクトを作ります
h = hashlib.new(algo)
# 分割する長さをブロックサイズの整数倍に決めます
Length = hashlib.new(algo).block_size * 0x800
# 大きなバイナリデータを用意します
path = 'test.zip'
with open(path,'rb') as f:
BinaryData = f.read(Length)
# データがなくなるまでループします
while BinaryData:
# ハッシュオブジェクトに追加して計算します。
h.update(BinaryData)
# データの続きを読み込む
BinaryData = f.read(Length)
# ハッシュオブジェクトを16進数で出力します
print(algo,h.hexdigest())
結果
md5 58c647b74f394f1cadef669607f59ab8
フリーソフトの**WinMD5 Free**でも同一の結果が得られました。
*** #### バイナリデータ 文字列やファイルをバイナリデータとして扱います
# 文字列(str)をバイナリデータ(bytes)に変換する。
>>> BinaryData = b'abc'
# 文字列(str)をバイナリデータ(bytes)にエンコードする。
>>> BinaryData = 'abc'.encode('UTF-8')
# ファイルをバイナリモードで読み込む
>>> with open('test.txt','rb') as f:
BinaryData = f.read()
*** #### ハッシュアルゴリズム
利用できるアルゴリズム名はalgorithms_guaranteedやalgorithms_availableで確認できます。
# すべてのプラットフォームで使えるもの
>>> hashlib.algorithms_guaranteed
{'blake2s', 'sha256', 'sha224', 'sha512', 'sha1', 'sha3_256', 'blake2b', 'shake_128', 'sha3_512', 'md5', 'sha3_224', 'sha384', 'shake_256', 'sha3_384'}
# 利用中のプラットホームで使えるもの
>>> hashlib.algorithms_available
{'blake2s', 'md4', 'sha512', 'sha3_256', 'whirlpool', 'blake2b', 'blake2s256', 'sha3_512', 'md5', 'sha384', 'md5-sha1', 'sha3_384', 'mdc2', 'ripemd160', 'sha256', 'sha224', 'shake_128', 'sha3_224', 'sha1', 'shake_256', 'blake2b512'}
-参考-
hashlib --- セキュアハッシュおよびメッセージダイジェスト — Python 3.7.4 ドキュメント