有没有什么简单的方法可以在Python中生成(并检查)文件列表的MD5校验和?(我有一个小程序,我正在工作,我想确认文件的校验和)。
当前回答
您可以使用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(),这样你就不必转换回来。
其他回答
你可以利用这个壳层。
from subprocess import check_output
#for windows & linux
hash = check_output(args='md5sum imp_file.txt', shell=True).decode().split(' ')[0]
#for mac
hash = check_output(args='md5 imp_file.txt', shell=True).decode().split('=')[1]
我显然没有添加任何根本性的新内容,但在我达到评论状态之前添加了这个答案,加上代码区域使事情更加清晰——无论如何,特别回答@Nemo的问题来自Omnifarious的回答:
我碰巧想到了一些校验和(来这里寻找关于块大小的建议),并发现这种方法可能比您预期的要快。用最快的时间(但非常典型)。Timeit或/usr/bin/time是对一个约为。11 mb:
$ ./sum_methods.py
crc32_mmap(filename) 0.0241742134094
crc32_read(filename) 0.0219960212708
subprocess.check_output(['cksum', filename]) 0.0553209781647
md5sum_mmap(filename) 0.0286180973053
md5sum_read(filename) 0.0311000347137
subprocess.check_output(['md5sum', filename]) 0.0332629680634
$ time md5sum /tmp/test.data.300k
d3fe3d5d4c2460b5daacc30c6efbc77f /tmp/test.data.300k
real 0m0.043s
user 0m0.032s
sys 0m0.010s
$ stat -c '%s' /tmp/test.data.300k
11890400
所以,看起来Python和/usr/bin/md5sum对于一个11MB的文件都需要大约30ms。相关的md5sum函数(上面清单中的md5sum_read)与Omnifarious的非常相似:
import hashlib
def md5sum(filename, blocksize=65536):
hash = hashlib.md5()
with open(filename, "rb") as f:
for block in iter(lambda: f.read(blocksize), b""):
hash.update(block)
return hash.hexdigest()
当然,这些都是来自单次运行(mmap的运行至少几十次时总是稍微快一点),而我的通常在缓冲区耗尽后得到一个额外的f.read(blocksize),但它是合理的可重复的,并表明命令行上的md5sum不一定比Python实现更快……
编辑:很抱歉长时间的延迟,已经有一段时间没有看这个了,但为了回答@EdRandall的问题,我将写下一个Adler32实现。但是,我还没有运行它的基准测试。它基本上与CRC32相同:而不是init、update和摘要调用,一切都是一个zlib.adler32()调用:
import zlib
def adler32sum(filename, blocksize=65536):
checksum = zlib.adler32("")
with open(filename, "rb") as f:
for block in iter(lambda: f.read(blocksize), b""):
checksum = zlib.adler32(block, checksum)
return checksum & 0xffffffff
注意,这必须从空字符串开始,因为Adler和从0开始与“”的和(1)确实不同——CRC可以从0开始。需要AND-ing使其成为32位无符号整数,以确保它在不同Python版本中返回相同的值。
你可以使用simple-file-checksum1,它只使用subprocess来调用macOS/Linux的openssl和Windows的CertUtil,并只从输出中提取摘要:
安装:
pip install simple-file-checksum
用法:
>>> from simple_file_checksum import get_checksum
>>> get_checksum("path/to/file.txt")
'9e107d9d372bb6826bd81d3542a419d6'
>>> get_checksum("path/to/file.txt", algorithm="MD5")
'9e107d9d372bb6826bd81d3542a419d6'
支持SHA1、SHA256、SHA384、SHA512四种算法。
披露:我是simple-file-checksum的作者。
hashlib.md5(pathlib.Path('path/to/file').read_bytes()).hexdigest()
您可以使用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(),这样你就不必转换回来。
推荐文章
- 如何在Python中进行热编码?
- 如何嵌入HTML到IPython输出?
- 在Python生成器上使用“send”函数的目的是什么?
- 是否可以将已编译的.pyc文件反编译为.py文件?
- Django模型表单对象的自动创建日期
- 在Python中包装长行
- 如何计算两个时间串之间的时间间隔
- 我如何才能找到一个Python函数的参数的数量?
- 您可以使用生成器函数来做什么?
- 将Python诗歌与Docker集成
- 提取和保存视频帧
- 使用请求包时出现SSL InsecurePlatform错误
- 如何检索Pandas数据帧中的列数?
- except:和except的区别:
- 错误:“字典更新序列元素#0的长度为1;2是必需的”