我使用过hashlib(它取代了Python 2.6/3.0中的md5),如果我打开一个文件并将其内容放在hashlib.md5()函数中,它工作得很好。

问题是对于非常大的文件,它们的大小可能超过RAM大小。

如何在不将整个文件加载到内存的情况下获得文件的MD5哈希值?


当前回答

我不喜欢循环。根据Nathan Feger的回答:

md5 = hashlib.md5()
with open(filename, 'rb') as f:
    functools.reduce(lambda _, c: md5.update(c), iter(lambda: f.read(md5.block_size * 128), b''), None)
md5.hexdigest()

其他回答

以下是我对Piotr Czapla方法的看法:

def md5sum(filename):
    md5 = hashlib.md5()
    with open(filename, 'rb') as f:
        for chunk in iter(lambda: f.read(128 * md5.block_size), b''):
            md5.update(chunk)
    return md5.hexdigest()
import hashlib,re
opened = open('/home/parrot/pass.txt','r')
opened = open.readlines()
for i in opened:
    strip1 = i.strip('\n')
    hash_object = hashlib.md5(strip1.encode())
    hash2 = hash_object.hexdigest()
    print hash2

使用多个评论/回答这个问题,以下是我的解决方案:

import hashlib
def md5_for_file(path, block_size=256*128, hr=False):
    '''
    Block size directly depends on the block size of your filesystem
    to avoid performances issues
    Here I have blocks of 4096 octets (Default NTFS)
    '''
    md5 = hashlib.md5()
    with open(path,'rb') as f:
        for chunk in iter(lambda: f.read(block_size), b''):
             md5.update(chunk)
    if hr:
        return md5.hexdigest()
    return md5.digest()

这是python式的 这是一个函数 它避免隐式值:总是偏爱显式值。 它允许(非常重要的)性能优化

将文件分解为8192字节的块(或其他128字节的倍数),并使用update()将它们连续地馈送给MD5。

这利用了MD5有128字节摘要块的事实(8192是128×64)。由于不是将整个文件读入内存,因此使用的内存不会超过8192个字节。

在Python 3.8+中你可以这样做

import hashlib
with open("your_filename.txt", "rb") as f:
    file_hash = hashlib.md5()
    while chunk := f.read(8192):
        file_hash.update(chunk)
print(file_hash.digest())
print(file_hash.hexdigest())  # to get a printable str instead of bytes

如果不阅读完整的内容,就无法获得它的md5。但是您可以使用update函数逐块读取文件的内容。

m.update(一个);M.update (b)等价于M.update (a+b)。