获取md5校验和的完成百分比

3 投票
3 回答
1058 浏览
提问于 2025-04-17 12:31

我现在得到了一个md5校验和,内容如下:

>>> import hashlib
>>> f = open(file)
>>> m = hashlib.md5()
>>> m.update(f.read())
>>> checksum = m.hedxigest()

我需要返回一个大视频文件的校验和,这个过程会花费几分钟的时间。请问我该如何实现一个百分比计数器,让它在运行时每完成一个百分比就打印出来。就像这样:

>>> checksum = m.hedxigest()
1% done...
2% done...
etc.

3 个回答

4

你应该用 f.read(N_BYTES) 这个方法分块读取文件,也就是一次读取一部分。然后要记得你已经读取到了文件的哪个位置,再把这些读取到的部分传给 m.update。这个 m.update 的操作比较耗时,而不是 md5.hexdigest

4

其实,耗时的不是 hedxigest() 这个调用,而是读取文件的过程。

考虑到这一点,可以把 m.update(f.read()) 替换成一个循环,逐块读取文件,更新校验和,并定期打印出进度报告。

9

你可以多次调用 update() 方法,并将文件分成小块逐步传给它。这样,你就可以自己显示进度。

import hashlib
import os

def digest_with_progress(filename, chunk_size):
    read_size = 0
    last_percent_done = 0
    digest = hashlib.md5()
    total_size = os.path.getsize(filename)

    data = True
    f = open(filename)
    while data:
        # Read and update digest.
        data = f.read(chunk_size)
        read_size += len(data)
        digest.update(data)

        # Calculate progress.
        percent_done = 100 * read_size / total_size
        if percent_done > last_percent_done:
            print '%d%% done' % percent_done
            last_percent_done = percent_done
    f.close()
    return digest.hexdigest()

当我尝试 print digest_with_progress('/bin/bash', 1024) 时,得到的结果是:

1% done
2% done
3% done
4% done
5% done
6% done
7% done
8% done
9% done
10% done
11% done
12% done
13% done
14% done
15% done
16% done
17% done
18% done
19% done
20% done
21% done
22% done
23% done
24% done
25% done
26% done
27% done
28% done
29% done
30% done
31% done
32% done
33% done
34% done
35% done
36% done
37% done
38% done
39% done
40% done
41% done
42% done
43% done
44% done
45% done
46% done
47% done
48% done
49% done
50% done
51% done
52% done
53% done
54% done
55% done
56% done
57% done
58% done
59% done
60% done
61% done
62% done
63% done
64% done
65% done
66% done
67% done
68% done
69% done
70% done
71% done
72% done
73% done
74% done
75% done
76% done
77% done
78% done
79% done
80% done
81% done
82% done
83% done
84% done
85% done
86% done
87% done
88% done
89% done
90% done
91% done
92% done
93% done
94% done
95% done
96% done
97% done
98% done
99% done
100% done
b114ecaab65bc5b02f5a129bd29d1864

这里是这个文件的具体信息。

$ ls -l /bin/bash; md5sum /bin/bash
-rwxr-xr-x 1 root root 971384 Nov 30 16:31 /bin/bash
b114ecaab65bc5b02f5a129bd29d1864  /bin/bash

注意,如果你把 chunk_size 设置得太大,你可能得不到预期的结果。例如,如果我们一次读取 100 KB 的数据,而不是 1 KB 的数据来处理 /bin/bash,你会看到这样的结果。

10% done
21% done
31% done
42% done
52% done
63% done
73% done
84% done
94% done
100% done
b114ecaab65bc5b02f5a129bd29d1864

这种方法的限制在于,我们只有在读取了一块数据后才能计算进度。所以,如果块的大小太大,每次读取一块并更新摘要时,进度的百分比变化可能会超过 1%。虽然大块数据处理起来会快一些,但你可能需要放宽每次打印进度百分比的条件,以提高效率。

撰写回答