ユースケースによって異なります。
偶発的な衝突だけが心配な場合は、MD5 と SHA-1 の両方で問題なく、一般的に MD5 の方が高速です。実際、MD4 はほとんどのユースケースで十分であり、通常はさらに高速ですが、広く実装されているわけではありません。(特に、それは含まれていませんhashlib.algorithms_guaranteed
... ただし、hashlib_algorithms_available
ほとんどのストック Mac、Windows、および Linux ビルドには含まれているはずです。)
一方、意図的な攻撃 (つまり、ハッシュに一致する偽のファイルを意図的に作成する誰か) を心配している場合は、保護しているものの価値を考慮する必要があります。MD4 ではほぼ間違いなく十分ではありません。MD5 ではおそらく十分ではありませんが、SHA-1 は限界です。現在、Keccak (まもなく SHA-3 になる予定) が最善の策であると考えられていますが、状況は毎年変化するため、これを常に把握しておく必要があります。
暗号化ハッシュ関数に関するウィキペディアのページには、通常かなり頻繁に更新される表があります。表を理解するには:
MD4 に対する衝突を生成するには 3 ラウンドしか必要としませんが、MD5 では約 200 万回、SHA-1 では 15 兆回必要です。これは、衝突を生成するのに (現在の価格で) 数百万ドルかかることを意味します。それはあなたにとって十分かもしれませんし、そうでないかもしれませんが、NIST にとっては十分ではありません。
また、「一般的に速い」ということは、「私のデータとプラットフォームでより速くテストされた」ということほど重要ではないことを覚えておいてください。それを念頭に置いて、私の Mac の 64 ビット Python 3.3.0 で、1MB のランダムbytes
オブジェクトを作成し、次のようにしました。
In [173]: md4 = hashlib.new('md4')
In [174]: md5 = hashlib.new('md5')
In [175]: sha1 = hashlib.new('sha1')
In [180]: %timeit md4.update(data)
1000 loops, best of 3: 1.54 ms per loop
In [181]: %timeit md5.update(data)
100 loops, best of 3: 2.52 ms per loop
In [182]: %timeit sha1.update(data)
100 loops, best of 3: 2.94 ms per loop
ご覧のとおりmd4
、他のものよりも大幅に高速です。
hashlib.md5()
の代わりに をhashlib.new('md5')
使用したテストとbytes
、少ないエントロピー (string.ascii_letters
スペースで区切られた 1 ~ 8 の実行) を使用したテストでは、有意な差は見られませんでした。
また、私のインストールに付属のハッシュ アルゴリズムについては、以下でテストしたように、md4 に勝るものはありません。
for x in hashlib.algorithms_available:
h = hashlib.new(x)
print(x, timeit.timeit(lambda: h.update(data), number=100))
速度が非常に重要な場合は、これを改善するために使用できる優れたトリックがあります。 のような悪いが非常に高速なハッシュ関数を使用し、zlib.adler32
各ファイルの最初の 256KB にのみ適用します。(ファイルの種類によっては、最後の 256KB や、最初の 256KB よりも中央に近い 256KB の方がよい場合があります。) 次に、衝突が見つかった場合は、MD4/SHA-1/Keccak/任意のハッシュを生成します。各ファイルのファイル全体。
最後に、誰かがコメントで、ファイル全体をメモリに読み込まずにファイルをハッシュする方法を尋ねたので:
def hash_file(path, algorithm='md5', bufsize=8192):
h = hashlib.new(algorithm)
with open(path, 'rb') as f:
block = f.read(bufsize)
if not block:
break
h.update(block)
return h.digest()
すべてのパフォーマンスを引き出すことが重要な場合はbufsize
、プラットフォームでさまざまな値 (4KB から 8MB までの 2 のべき乗) を試してください。os.open
生のファイル ハンドル (および)を使用して実験することもできos.read
ます。これは、一部のプラットフォームでは高速になる場合があります。