Python MD5 哈希快速计算

3 投票
4 回答
8529 浏览
提问于 2025-04-15 22:36

我会尽量详细地解释我的问题和我想到的解决办法。

我使用了这段代码:

    for root, dirs, files in os.walk(downloaddir):
for infile in files:
    f = open(os.path.join(root,infile),'rb')
    filehash = hashlib.md5()
    while True:
        data = f.read(10240)
        if len(data) == 0:
            break
        filehash.update(data)
    print "FILENAME: " , infile
    print "FILE HASH: " , filehash.hexdigest()

然后我用 start = time.time() 和 elapsed = time.time() - start 来测量计算一个哈希值需要多长时间。当我把代码指向一个大小为653MB的文件时,结果是:

root@Mars:/home/tiago# python algorithm-timer.py 
FILENAME:  freebsd.iso
FILE HASH:  ace0afedfa7c6e0ad12c77b6652b02ab
          12.624
root@Mars:/home/tiago# python algorithm-timer.py 
FILENAME:  freebsd.iso
FILE HASH:  ace0afedfa7c6e0ad12c77b6652b02ab
          12.373
root@Mars:/home/tiago# python algorithm-timer.py 
FILENAME:  freebsd.iso
FILE HASH:  ace0afedfa7c6e0ad12c77b6652b02ab
          12.540

好的,现在在处理一个653MB的文件时大约需要12秒。我的问题是,我打算在一个程序中使用这段代码,这个程序会处理多个文件,其中一些可能有4GB、5GB或6GB,这样计算的时间会更长。我在想有没有更快的方法来计算文件的哈希值?也许可以使用多线程?我用另一个脚本每秒检查一次CPU的使用情况,发现我的代码只在使用2个CPU中的1个,而且最多只使用了25%。有没有办法可以改变这种情况?

谢谢大家提前提供的帮助。

4 个回答

2

就我个人的经验来说,执行这个操作:

c:\python\Python.exe c:\python\Tools\scripts\md5sum.py cd.iso

在我的笔记本电脑上花了9.671秒(我的电脑是2GHz的双核处理器,配有80GB的SATA硬盘)。

正如其他人提到的,MD5的计算主要受硬盘速度的影响,不过你提到的12秒的测试结果可能已经接近最快的速度了。

另外,Python的md5sum.py使用的缓冲区大小是8096(虽然我相信他们其实是想用4096或8192)。

2

我发现增加缓冲区的大小对我有帮助,但也有个限度。我一开始设置为1024,然后每次都把它乘以2的N次方,从N=1开始逐渐增加。通过这种方法,我发现我的系统上,缓冲区大小设置为65536似乎是最好的选择。不过,这样做只让我运行时间提高了大约7%。

分析显示,大约80%的时间都花在了MD5更新方法上,剩下的20%则是在读取文件。由于MD5是一种串行算法,而Python中的算法已经用C语言实现了,我觉得在加速MD5部分上能做的事情不多。你可以尝试同时计算两个不同文件的MD5值,但正如大家所说的,最终你还是会受到磁盘访问速度的限制。

4

在你的情况下,哈希计算几乎肯定会受到输入输出速度的限制(除非你在一台处理器非常慢的机器上运行)。所以,使用多线程或者同时处理多个文件,可能不会给你带来预期的效果。

把文件分散到多个硬盘上,或者放在更快的硬盘(比如固态硬盘SSD)上,可能会有所帮助,尽管这可能不是你想要的解决方案。

撰写回答