这取决于您的使用案例.
如果您只担心意外碰撞,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
Run Code Online (Sandbox Code Playgroud)
如您所见,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))
Run Code Online (Sandbox Code Playgroud)
如果速度非常重要,那么可以使用一个很好的技巧来改进:使用一个糟糕但非常快速的哈希函数,例如zlib.adler32,只将它应用于每个文件的前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()
Run Code Online (Sandbox Code Playgroud)
如果挤出每一点性能很重要,那么你需要bufsize在你的平台上试验不同的值(2的功率从4KB到8MB).您还可能希望尝试使用原始文件句柄(os.open和os.read),这在某些平台上有时会更快.
| 归档时间: |
|
| 查看次数: |
2107 次 |
| 最近记录: |