LoginSignup
8
6

More than 3 years have passed since last update.

Python3でファイルのハッシュを計算する。

Last updated at Posted at 2018-09-03

ファイルが同一であるか調べるのに便利です。

使い方

バイナリデータを指定したハッシュアルゴリズムで計算し、バイナリの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_guaranteedalgorithms_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 ドキュメント

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6