Hashlib Python模块update方法中字节的最大限制

3 投票
3 回答
2529 浏览
提问于 2025-04-16 11:31

我正在尝试使用hashlib.md5()这个函数来计算一个文件的md5哈希值,这个函数来自hashlib模块。

所以我写了这段代码:

Buffer = 128
f = open("c:\\file.tct", "rb")
m = hashlib.md5()

while True:
   p = f.read(Buffer)
   if len(p) != 0:
      m.update(p)
   else:
      break
print m.hexdigest()
f.close()

我注意到,如果我把Buffer变量的值增加到64、128、256等等,函数的更新速度会更快。请问有没有一个上限是我不能超过的?我想这可能只是内存的问题,但我不太确定。

3 个回答

0

缓冲区的值就是一次性读取并存储到内存中的字节数,所以说,唯一的限制就是你可用的内存大小。

不过,缓冲区的值越大并不意味着速度就一定越快。如果设置的缓冲区太大,你可能会遇到内存分页的问题或者其他导致内存分配变慢的情况。因此,你应该尝试逐渐增大这个值,直到发现速度提升不再明显为止。

2

为了处理非常大的文件,我们需要分块来读取它们。这样的块的大小最好是2的幂次方。以md5算法为例,最小的块大小是64字节(也就是512位),因为这个算法是以512位的块为单位来工作的。

但是如果我们想要准确判断,比如2048字节的块是否比4096字节的块“更好”,那就可能会遇到困难。这需要非常仔细的测试和测量,通常情况下,块的大小是根据经验随意选择的。

3

使用很大的块大小(大约是2**40)会导致MemoryError,也就是说,除了可用的内存外,没有其他限制。另一方面,我的机器上bufsize的限制是2**31-1

import hashlib
from functools import partial

def md5(filename, chunksize=2**15, bufsize=-1):
    m = hashlib.md5()
    with open(filename, 'rb', bufsize) as f:
        for chunk in iter(partial(f.read, chunksize), b''):
            m.update(chunk)
    return m

很大的chunksize可能和非常小的块一样慢。你可以测量一下。

我发现对于大约10MB的文件,2**15chunksize是我测试过的文件中速度最快的。

撰写回答