7

さまざまなデバイスにあるMP3を追跡するために、簡単なMP3カタログを作成しています。名前が変更されたり移動されたりした場合でも、MD5またはSHA2キーを使用して一致するファイルを識別することを計画していました。論理的に同等の(つまり、同じ曲であるがエンコードが異なる)MP3を一致させようとはしていません。私は約8000のMP3を持っています。それらのうち約6700のみが一意のキーを生成しました。

私の問題は、選択したハッシュアルゴリズムに関係なく、衝突が発生していることです。あるケースでは、同じアルバムのトラック#1と#2である2つのファイルがあります。これらはファイルサイズが異なりますが、MD5、SHA2-256、SHA2-512などを使用しても同じハッシュキーを生成します。

ファイルにハッシュキーを実際に使用するのはこれが初めてであり、これは予期しない結果です。これらのハッシュアルゴリズムについて私が知っていることから、ここで何か怪しいことが起こっているように感じます。これはMP3またはPythonの実装に関連する問題でしょうか?

これが私が使用しているコードのスニペットです:

    data = open(path, 'r').read()

    m = hashlib.md5(data)

    m.update(data)

    md5String = m.hexdigest()

なぜこれが起こっているのかについての答えや洞察をいただければ幸いです。前もって感謝します。

--更新-:

Linux(Python 2.6を使用)でこのコードを実行しようとしましたが、衝突は発生しませんでした。stat呼び出しで示されているように、ファイルは同じではありません。WinMD5もダウンロードしましたが、衝突は発生しませんでした(8d327ef3937437e0e5abbf6485c24bb3および9b2c66781cbe8c1be7d6a1447994430c)。これはWindows上のPythonhashlibのバグですか?Python 2.7.1と2.6.6で同じことを試しましたが、どちらも同じ結果になりました。

import hashlib
import os

def createMD5( path):

    fh = open(path, 'r')
    data = fh.read()
    m = hashlib.md5(data)
    md5String = m.hexdigest()
    fh.close()
    return md5String

print os.stat(path1)
print os.stat(path2)
print createMD5(path1)
print createMD5(path2)

>>> nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=6617216L, st_atime=1303808346L, st_mtime=1167098073L, st_ctime=1290222341L)
>>> nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=4921346L, st_atime=1303808348L, st_mtime=1167098076L, st_ctime=1290222341L)   
>>> a7a10146b241cddff031eb03bd572d96
>>> a7a10146b241cddff031eb03bd572d96
4

4 に答える 4

9

予想よりも小さいデータのチャンクを読んでいるような気がしますが、このチャンクは両方のファイルで同じです。理由はわかりませんが、「rb」を使用してファイルをバイナリで開こうとします。read()はファイルの終わりまで読み取る必要がありますが、Windowsの動作は異なります。ドキュメントから

Windowsでは、モードに「b」を追加するとファイルがバイナリモードで開くため、「rb」、「wb」、「r+b」などのモードもあります。Windows上のPythonは、テキストファイルとバイナリファイルを区別します。テキストファイルの行末文字は、データの読み取りまたは書き込み時に自動的にわずかに変更されます。このファイルデータの舞台裏での変更は、ASCIIテキストファイルには問題ありませんが、JPEGまたはEXEファイルのようなバイナリデータが破損します。このようなファイルを読み書きするときは、バイナリモードの使用に十分注意してください。Unixでは、モードに「b」を追加しても問題はないため、すべてのバイナリファイルに対してプラットフォームに依存せずに使用できます。

于 2011-04-26T11:15:30.577 に答える
2

問題が発生しているファイルは、いくつかの異なるハッシュアルゴリズムがすべて同じハッシュ結果を返す場合、または実装にバグがある場合、ほぼ確実に同一です。

健全性テストとして、ファイルの内容を完全に返す独自の「ハッシュ」を作成し、これが同じ「ハッシュ」を生成するかどうかを確認します。

于 2011-04-26T08:01:41.833 に答える
2

他の人が述べているように、ファイルが同一でない限り、単一のハッシュ衝突は起こりそうになく、複数の衝突は不可能に近いです。健全性チェックのようなものとして、外部ユーティリティを使用して合計を生成することをお勧めします。たとえば、Ubuntu(および他のほとんど/すべてのLinuxディストリビューション)では、次のようになります。

blair@blair-eeepc:~$ md5sum Bandwagon.mp3
b87cbc2c17cd46789cb3a3c51a350557  Bandwagon.mp3
blair@blair-eeepc:~$ sha256sum Bandwagon.mp3 
b909b027271b4c3a918ec19fc85602233a4c5f418e8456648c426403526e7bc0  Bandwagon.mp3

グーグルで簡単に検索すると、Windowsマシンで利用できる同様のユーティリティがあることがわかります。外部ユーティリティとの衝突が見られる場合、ファイルは同一です。衝突がない場合は、何か問題があります。Pythonでハッシュを実行しても同じ結果が得られるため、Pythonの実装が間違っているとは思えません。

>>> import hashlib
>>> hashlib.md5(open('Bandwagon.mp3', 'r').read()).hexdigest()
'b87cbc2c17cd46789cb3a3c51a350557'
>>> hashlib.sha256(open('Bandwagon.mp3', 'r').read()).hexdigest()
'b909b027271b4c3a918ec19fc85602233a4c5f418e8456648c426403526e7bc0'
于 2011-04-26T08:23:16.870 に答える
0

@Delan Azabaniが言ったように、ここには何か怪しいものがあります。衝突は必ず発生しますが、それほど頻繁ではありません。曲が同じかどうかを確認し、投稿を更新してください。

また、十分なキーがないと感じた場合は、2つ(またはそれ以上)のハッシュアルゴリズムを同時に使用できます。たとえば、MD5を使用すると2**128、または340282366920938463463374607431768211456キーがあります。SHA-1を使用すると、2**160または1461501637330902918203684832716283019655932542976キーが得られます。それらを組み合わせることにより、、、2**128 * 2**160またはがあり497323236409786642155382248146820840100456150797347717440463976893159497012533375533056ます。

(しかし、私に言わせれば、MD5はあなたのニーズには十分すぎるほどです。)

于 2011-04-26T08:08:09.520 に答える