有没有什么简单的方法可以在Python中生成(并检查)文件列表的MD5校验和?(我有一个小程序,我正在工作,我想确认文件的校验和)。
当前回答
你可以使用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的作者。
其他回答
你可以使用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的作者。
在Python 3.11+中,有一个新的可读且内存高效的方法:
import hashlib
with open(path, "rb") as f:
digest = hashlib.file_digest(f, "md5")
print(digest.hexdigest())
你可以利用这个壳层。
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版本中返回相同的值。
hashlib.md5(pathlib.Path('path/to/file').read_bytes()).hexdigest()
推荐文章
- 如何在Django模板中获得我的网站的域名?
- 在django Forms中定义css类
- 如何在Python中scp ?
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?
- 第一次出现的值大于现有值的Numpy
- 如何从Python函数中返回两个值?
- 前一个月的Python日期
- Python中方括号括起来的列表和圆括号括起来的列表有什么区别?
- Python日志记录不输出任何东西
- 每n秒运行特定代码
- SQLAlchemy是否有与Django的get_or_create等价的函数?