ハッシュ関数

ハッシュ関数

データを切り刻んで混ぜ、一定の長さ(例えば256ビット)のデータに変換する関数を、ハッシュ関数といいます(ここでは特に暗号学的ハッシュ関数と呼ばれるものを扱います)。ハッシュ関数の値をハッシュ値または単にハッシュといいます。256ビットに変換するハッシュ関数ではSHA-256(シャー256)がよく使われます。

以下では、Python の標準ライブラリ hashlib を使います。

例えば "The quick brown fox jumps over the lazy dog." という44バイトの文字列のSHA-256を求めてみましょう:

import hashlib

hashlib.sha256("The quick brown fox jumps over the lazy dog.".encode()).hexdigest()
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c'

長さ64の文字列が出力されましたが、これは16進法で表した256ビットの数です。

ここで、データ "The quick brown fox ..." をほんの少し改ざんしてみましょう。どこが変わったかわかるでしょうか。

hashlib.sha256("The quick brown fox jumps over the lazy dоg.".encode()).hexdigest()
'dcdfe505588cb616e6cbf8a3aeea22f14cf5242ff06f0e1887d6af7b7c188b88'

微妙な改ざんなので気づかないかもしれませんが、SHA-256の値は確かに変わっています。このように、ハッシュはデータのほんのちょっとの変化でも確実に捉えます。

ハッシュの計算時間を調べてみましょう。

%timeit hashlib.sha256("The quick brown fox jumps over the lazy dog.".encode()).hexdigest()

私の Mac mini (M1, 2020) の結果:

387 ns ± 0.874 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

1回あたり 387 ナノ秒 = 387×10-9 秒ですので、260 MH/s(メガハッシュ毎秒)ほどです。

→ Bitcoin Wiki: Block hashing algorithm

[追記]Python 3.11 でファイルのハッシュが簡単に求められるようになりました:

import hashlib

with open("filename", "rb") as f:
    digest = hashlib.file_digest(f, "sha256")
print(digest.hexdigest())

Last modified: