2011-04-26 5 views
7

간단한 MP3 카탈로그를 작성하여 다양한 MP3에 어떤 트랙이 있는지 추적합니다. MD5 또는 SHA2 키를 사용하여 이름이 바뀌거나 이동 된 경우에도 일치하는 파일을 식별 할 계획이었습니다. 논리적으로 동일한 MP3를 (즉, 동일한 노래이지만 인코딩이 다르게) 일치시키려는 것이 아닙니다. 나는 약 8000 MP3를 가지고있다. 약 6700 개만 고유 키를 생성했습니다.Python의 MD5 및 SHA-2 충돌

내 문제는 내가 선택한 해시 알고리즘에 관계없이 충돌이 발생한다는 것입니다. 하나의 경우, 나는 같은 앨범에서 트랙 # 1과 # 2가되는 두 개의 파일을 가지고 있는데, MD5, SHA2-256, SHA2-512 등을 사용하더라도 파일 크기가 다르지만 동일한 해시 키를 생성합니다.

파일에서 해시 키를 실제로 사용하는 것은 이번이 처음이며 예기치 않은 결과입니다. 나는이 해싱 알고리즘에 대해 알고있는 작은 것에서 비린내가 일어나고 있다고 느낍니다. 이것이 MP3 또는 파이썬의 구현과 관련된 문제 일 수 있습니까?

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

    m = hashlib.md5(data) 

    m.update(data) 

    md5String = m.hexdigest() 

어떤 답변이나이 많이 주시면 감사하겠습니다 일어나는 이유에 대한 통찰력을 :

는 여기에 내가 사용하고 코드의 조각입니다. 미리 감사드립니다.

--UPDATE--

는 :

나는 (파이썬 2.6) 리눅스에서이 코드를 실행 시도하고 충돌을 발생하지 않았다. stat 호출에서 보여 주듯이 파일은 동일하지 않습니다. 또한 WinMD5를 다운로드했는데 충돌이 발생하지 않았습니다 (8d327ef3937437e0e5abbf6485c24bb3 및 9b2c66781cbe8c1be7d6a1447994430c). 이 버그는 Windows에서 Python hashlib의 버그입니까? 파이썬 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 
+5

MP3 파일이 실제로 실제로 다른가요? 특히 SHA-1 및 SHA-2와 같이 더 크고 고급 알고리즘의 경우 해싱 충돌이 거의 발생하지 않습니다. 충돌이 많으면 실제로 중복 파일이 많을 수도 있습니다. –

+1

BTW, 왜 m.update()를 호출합니까? m = hashlib.md5 ("foo"); m.update ("foo")는 m = hashlib.md5 ("foofoo")와 동일합니다. –

답변

8

나는 당신이 예상보다 작은 데이터 덩어리를 읽고있는 느낌이 종류의, 그리고 이 청크는 두 파일에서 동일하게 발생합니다. 이유를 모르겠지만 'rb'로 이진 파일을 열어보십시오. read()는 파일의 끝까지 읽어야하지만 윈도우는 다르게 동작합니다. 'B'워드 프로세서 Windows에서

,에서 모드 에 추가 그래서 또한 'RB', 'WB', 와 'R + B'와 같은 모드가 있습니다, 바이너리 모드로 파일을 엽니 다. Windows상의 파이썬은 텍스트와 바이너리를 구별합니다. 파일; 텍스트 파일의 줄 끝 문자는 데이터를 읽거나 쓸 때 약간 으로 자동 변경됩니다. ASCII 데이터 파일의 경우 파일 데이터의 배후 수정이 적합하지만 JPEG 또는 EXE 파일의 이진 데이터 이 손상됩니다. 과 같은 파일을 읽고 쓰는 경우 바이너리 모드를 사용할 때 매우주의해야합니다. 유닉스에서는 'b'를이 모드에 추가하지 않으므로 모든 바이너리 파일에 대해 플랫폼 독립적으로 사용할 수 있습니다.

+0

open (path , 'r') open (path, 'rb')이 트릭을 만들었습니다. 이제 두 개의 별개의 키를 얻습니다. – Jesse

2

파일은 거의 확실 동일, 또는 구현에 버그가있다.

위생 테스트로 파일의 내용을 전체적으로 반환하는 "해시"를 작성하고 동일한 "해시"를 생성하는지 확인하십시오.

+0

내 업데이트 된 게시물을 참조하십시오. 파일은 확실히 동일하지 않습니다. – Jesse

+0

@ 제시 : 흥미 롭습니다. 문제를 설명하는 Python 버그 (http://bugs.python.org/)를 열 것을 제안합니다. 여기서 중요한 것은 Windows에서 서로 다른 해시를 얻고 리눅스에서 동일한 해시를 갖는 2 개의 파일입니다. –

0

@Delan Azabani와 마찬가지로 여기에 뭔가 비린내가 있습니다. 충돌은 일어날 수밖에 없지만 자주 발생하지는 않습니다. 노래가 같은지 확인하고 게시물을 업데이트하십시오.

또한 충분한 키가 없다고 생각하면 동시에 두 개 이상의 해시 알고리즘을 사용할 수 있습니다. 예를 들어 MD5를 사용하면 2**128 또는 340282366920938463463374607431768211456 개의 키가 있습니다. SHA-1을 사용하면 2**160 또는 1461501637330902918203684832716283019655932542976 키가 있습니다. 조합하면 2**128 * 2**160 또는 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056이됩니다.

(당신이 저를 요구하는 경우에 그러나, MD5는 사용자의 요구에 충분하다.) 파일이 동일하지 않는

다른 사람이 언급 한 것처럼
1

, 하나의 해시 충돌, 가능성과 불가능에 가까이 여러이다. 나는 위생 검사로 뭔가를 외부 유틸리티를 사용하여 합계를 생성하는 것이 좋습니다 것입니다. 예를 들어, 우분투 (대부분/다른 모든 리눅스 배포판)에 :

[email protected]:~$ md5sum Bandwagon.mp3 
b87cbc2c17cd46789cb3a3c51a350557 Bandwagon.mp3 
[email protected]:~$ sha256sum Bandwagon.mp3 
b909b027271b4c3a918ec19fc85602233a4c5f418e8456648c426403526e7bc0 Bandwagon.mp3 

빠른 구글 검색

는 Windows 시스템에 사용할 유사한 유틸리티가 표시됩니다. 외부 유틸리티와의 충돌을 보면 파일이 동일합니다.충돌이 없다면, 당신은 뭔가 잘못하고있는 것입니다. 내가 파이썬 구현이 잘못 의심 나는 파이썬에서 해시를하고 같은 결과를 얻을 수로 :

>>> import hashlib 
>>> hashlib.md5(open('Bandwagon.mp3', 'r').read()).hexdigest() 
'b87cbc2c17cd46789cb3a3c51a350557' 
>>> hashlib.sha256(open('Bandwagon.mp3', 'r').read()).hexdigest() 
'b909b027271b4c3a918ec19fc85602233a4c5f418e8456648c426403526e7bc0'