如何使用Python创建文件的校验和。

5
我将尝试创建一个文件的校验和并将其保存为同名文件。所以我会监测这个文件,如果校验和发生变化,那么就会执行某些操作。
以下是校验和:
对于test.txt
contents: a
checksum: dd18bf3a8e0a2a3e53e2661c7fb53534

我编辑文件:
contents: aa
checksum: dd18bf3a8e0a2a3e53e2661c7fb53534

这是我的代码:

python -c 'import hashlib;print hashlib.md5("test.txt").hexdigest()'

为什么校验和是相同的?
3个回答

7

为什么校验和相同?

因为你正在计算相同内容的哈希值test.txt

以下是一款通用工具(克隆了广泛可用的md5sum CLI工具,适用于许多Linux和UNIX平台),可以很好地扩展大文件。

md5sum.py:

#!/usr/bin/env python

"""Tool to compuete md5 sums of files"""

import sys
from hashlib import md5


def md5sum(filename):
    hash = md5()
    with open(filename, "rb") as f:
        for chunk in iter(lambda: f.read(128 * hash.block_size), b""):
            hash.update(chunk)
    return hash.hexdigest()


def main():
    if len(sys.argv) < 2:
        print "Usage: md5sum <filename>"
        raise SystemExit(1)

    print md5sum(sys.argv[1])


if __name__ == "__main__":
    main()

这段内容是从https://bitbucket.org/prologic/tools/src/tip/md5sum借鉴而来的。


3
你可以尝试检查 hashlib.md5()
import hashlib
[(fname, hashlib.md5(open(fname, 'rb').read()).digest()) for fname in fnamelst]

1
这种方法无法处理大文件的规模。 - James Mills
不需要大文件。但我使用了hexdigest(),并且需要尽可能接近一行的代码。 - Tampa
MD5已经被破解,不应再使用。 - NDEthos
4
@NDEthos,你过于概括了。是的,在密码学环境中它有弱点,不应在那里使用。但在没有可能攻击者尝试制造冲突的情况下,MD5仍然完全可用。 - blubberdiblub

0

hashlib中的核心哈希函数接受要进行哈希处理的字符串内容,而不是要打开和读取的文件名,所以正如James所说,你在两种情况下都对相同的值'text.txt'进行哈希处理。

Python 3.11+

如果你只针对Python 3.11+版本,有一个新的选项可用:hashlib.file_digest()。它接受一个文件对象和一个哈希函数或hashlib哈希函数的名称。你尝试的等效方式如下:

import hashlib
with open('text.txt', 'rb') as file:
    print(hashlib.file_digest(file, 'md5').hexdigest())

Python 2.7-3.10+
尽管直到2026年10月,hashlib.file_digest() 在所有支持的Python版本上都不可用,但我们仍然可以深入了解其中的内容,以便了解如何使用bytearraymemoryview来创建一个更好的md5sum()版本,而不是使用iter(lambda: f.read())
import hashlib

def md5sum(filename, _bufsize=2**18):
    digest = hashlib.md5()
    
    buf = bytearray(_bufsize)
    view = memoryview(buf)
    with open(filename, 'rb') as file:
        while True:
            size = file.readinto(buf)
            if size == 0:
                break  # EOF
            digest.update(view[:size])
    
    return digest.hexdigest()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接