如何在Python中创建文件的校验和
我想给一个文件生成一个校验和,并把这个校验和保存成一个文件。这样的话,我就可以监控这个文件,如果校验和发生变化,我就可以采取一些行动。
这是校验和的内容:
对于 test.txt 文件:
contents: a
checksum: dd18bf3a8e0a2a3e53e2661c7fb53534
我编辑了这个文件:
contents: aa
checksum: dd18bf3a8e0a2a3e53e2661c7fb53534
这是我的代码:
python -c 'import hashlib;print hashlib.md5("test.txt").hexdigest()'
为什么这些校验和是一样的呢?
3 个回答
0
hashlib中的核心哈希函数是用来处理字符串内容的,而不是用来打开和读取文件名的。所以正如James所说,你在两种情况下哈希的都是同一个值'text.txt'
。
Python 3.11+
如果你只使用Python 3.11及以上版本,有一个新选项可以使用:hashlib.file_digest()
。这个函数可以接受一个文件对象和一个哈希函数,或者哈希函数的名称。你之前尝试的做法可以这样实现:
import hashlib
with open('text.txt', 'rb') as file:
print(hashlib.file_digest(file, 'md5').hexdigest())
Python 2.7-3.10+
虽然hashlib.file_digest()
在所有支持的Python版本上要到2026年10月才会可用,但我们仍然可以深入了解,看看如何用bytearray
和memoryview
来制作一个更好的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()
7
为什么这些校验和是一样的?
因为你计算的是同一个文件 test.txt
的哈希值。
这里有一个通用工具(它是一个类似于许多Linux和UNIX平台上常见的 md5sum
命令行工具的克隆),可以很好地处理大文件。
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()
3
你可以试着查看一下 hashlib.md5() 这个链接。
import hashlib
[(fname, hashlib.md5(open(fname, 'rb').read()).digest()) for fname in fnamelst]