Jes*_*sse 7 python hash mp3 md5 sha
我正在编写一个简单的MP3编目器来跟踪我的各种设备上的MP3.我计划使用MD5或SHA2键来识别匹配的文件,即使它们已被重命名/移动等等.我不是要匹配逻辑上相同的MP3(即:相同的歌曲,但编码方式不同).我有大约8000个MP3.其中只有约6700个生成了唯一的密钥.
我的问题是,无论我选择何种哈希算法,我都会遇到冲突.在一个案例中,我有两个文件碰巧是同一专辑中的曲目#1和#2,它们是不同的文件大小但产生相同的散列键,无论我使用MD5,SHA2-256,SHA2-512等...
这是我第一次真正在文件上使用哈希键,这是一个意想不到的结果.从我对这些散列算法的了解中,我觉得这里发生了一些可疑的事情.这可能是与MP3或Python实现相关的问题吗?
这是我正在使用的代码片段:
data = open(path, 'r').read()
m = hashlib.md5(data)
m.update(data)
md5String = m.hexdigest()
Run Code Online (Sandbox Code Playgroud)
任何有关为什么会发生这种情况的答案或见解将非常感激.提前致谢.
--UPDATE--:
我尝试在linux(使用Python 2.6)中执行此代码并且它没有产生冲突.如stat调用所示,文件不一样.我还下载了WinMD5,这并没有产生碰撞(8d327ef3937437e0e5abbf6485c24bb3和9b2c66781cbe8c1be7d6a1447994430c).这是Windows上的Python hashlib的错误吗?我在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
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,你正在读取一个小于预期的数据块,这两个文件的块相同.我不知道为什么,但尝试用'rb'打开二进制文件.read()应该读取到文件末尾,但是Windows的行为方式不同.来自文档
在Windows上,附加到模式的'b'以二进制模式打开文件,因此还有'rb','wb'和'r + b'等模式.Windows上的Python区分了文本和二进制文件; 读取或写入数据时,文本文件中的行尾字符会自动稍微改变.这种对文件数据的幕后修改适用于ASCII文本文件,但它会破坏像JPEG或EXE文件中的二进制数据.在读取和写入此类文件时要非常小心地使用二进制模式.在Unix上,将'b'附加到模式没有什么坏处,因此您可以独立于平台使用它来处理所有二进制文件.