生成文件的 MD5 校验和

新手上路,请多包涵

是否有任何简单的方法可以在 Python 中生成(和检查)文件列表的 MD5 校验和? (我有一个正在开发的小程序,我想确认文件的校验和)。

原文由 Alexander 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

您可以使用 hashlib.md5()

请注意,有时您无法将整个文件放入内存中。在这种情况下,您必须按顺序读取 4096 字节的块并将它们提供给 md5 方法:

 import hashlib
def md5(fname):
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

注意: hash_md5.hexdigest() 将返回摘要的 十六进制字符串 表示,如果您只需要打包字节使用 return hash_md5.digest() ,因此您不必转换回来。

原文由 quantumSoup 发布,翻译遵循 CC BY-SA 4.0 许可协议

有一种方法内存 效率很低

单个文件:

 import hashlib
def file_as_bytes(file):
    with file:
        return file.read()

print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()

文件清单:

 [(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

回想一下, 已知 MD5 已损坏,不应将其用于任何目的,因为漏洞分析可能非常棘手,并且分析您的代码将来可能用于安全问题的任何可能用途是不可能的。恕我直言,它应该从库中完全删除,这样每个使用它的人都被迫更新。所以,这是你应该做的:

 [(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

如果你只想要 128 位的摘要,你可以做 .digest()[:16]

这将为您提供一个元组列表,每个元组都包含其文件名及其哈希值。

我再次强烈质疑您对 MD5 的使用。您至少应该使用 SHA1,考虑到 最近在 SHA1 中发现的缺陷,可能甚至不会。有些人认为只要您不将 MD5 用于“加密”目的,就可以了。但是事情往往会比你最初预期的范围更广,你随意的漏洞分析可能会被证明是完全有缺陷的。最好养成一开始就使用正确算法的习惯。只需输入一串不同的字母即可。这并不难。

这是一种更复杂但 内存效率更高 的方法:

 import hashlib

def hash_bytestr_iter(bytesiter, hasher, ashexstr=False):
    for block in bytesiter:
        hasher.update(block)
    return hasher.hexdigest() if ashexstr else hasher.digest()

def file_as_blockiter(afile, blocksize=65536):
    with afile:
        block = afile.read(blocksize)
        while len(block) > 0:
            yield block
            block = afile.read(blocksize)

[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.md5()))
    for fname in fnamelst]

而且,再一次,因为 MD5 已经损坏,不应该再使用了:

 [(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
    for fname in fnamelst]

同样,如果您只想要 128 位的摘要,则可以在调用 hash_bytestr_iter(...) [:16] 之后放置 --- 。

原文由 Omnifarious 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题