我正在编写一个Python脚本来搜索具有相同MD5校验和(意味着这些文件相同)的文件的文件夹(作为命令行参数传递)并在屏幕上打印它们。
我使用os.walk()
函数扫描文件夹并编写了一个函数来计算MD5总和。但现在我无法弄清楚如何搜索具有相同MD5校验和的文件。你能帮帮我吗?
#/usr/bin/env python3
import sys
import hashlib
import os
import operator
###############################################
def md5checksum (filepath):
with open(filepath, "rb") as afile:
m=hashlib.md5()
data = afile.read()
m.update(data)
return m.hexdigest()
################################################
if __name__=="__main__":
dir1 = sys.argv[1]
info={}
stampa=[]
for path, dirname, filenames in os.walk(dir1):
for filename in filenames:
info[str(path)+filename]=md5checksum(str(path)+'/'+filename)
现在我想搜索并打印具有相同MD5校验和的元素。
答案 0 :(得分:1)
你快到了。关键是您必须反转字典的结构:为了轻松搜索具有相同校验和的文件,您可以使用MD5和作为键,以及列表将校验和作为值的路径:
{'6d4840fa80a877c234895ba45229d939': ['./search.py'],
'7dac6bd007fce17b0325a693fdb62c68': ['./foo/foo1/f.txt', './foo/foo1/f2.txt'],
'e7b39e258d9b15300d1732bfce9d89bd': ['./foo/foo1/f3.txt']}
然后检查结果归结为:特定校验和的路径列表中是否有多个条目?如果是,那些文件具有相同的校验和。
在这段代码中,我使用defaultdict
默认为列表,以避免检查字典中是否已存在校验和。
#!/usr/bin/env python3
from collections import defaultdict
import hashlib
import os
import sys
def md5checksum(filepath):
with open(filepath, "rb") as afile:
m = hashlib.md5()
data = afile.read()
m.update(data)
return m.hexdigest()
def calculate_checksums(search_dir):
checksums = defaultdict(list)
for root, dirs, files in os.walk(search_dir):
for filename in files:
path = os.path.join(root, filename)
checksum = md5checksum(path)
checksums[checksum].append(path)
return checksums
def display_equal_files(checksums):
for checksum, paths in checksums.items():
if len(paths) > 1:
print("MD5 sum: {}".format(checksum))
for path in paths:
print(" {}".format(path))
if __name__ == "__main__":
search_dir = sys.argv[1]
checksums = calculate_checksums(search_dir)
display_equal_files(checksums)
示例输出:
MD5 sum: 8863775ebac6399b538c852e5ee03559
./bar/bar.txt
./baz/bar2.txt
MD5 sum: 7dac6bd007fce17b0325a693fdb62c68
./foo/foo1/f.txt
./foo/foo1/f2.txt
一对夫妇注意到:
#!/
而不是#/
md5checksums()
函数中的缩进错误。缩进在Python中非常重要,请确保密切关注它。os.path.join
加入文件路径。答案 1 :(得分:0)
您需要跟踪每个哈希的冲突文件名(即从哈希到具有该哈希的文件的文件名的映射)。最简单的方法是使用defaultdict
。
以下代码为您提供了一个字典hashes
,其中包含MD5校验和的键,以及包含该校验和的文件列表。然后,您可以使用多个项目轻松过滤列表值(即两个或多个具有相同哈希值的文件)。
#/usr/bin/env python3
import sys
import hashlib
import os
import operator
from collections import defaultdict
###############################################
def md5checksum (filepath):
with open(filepath, "rb") as afile:
m=hashlib.md5()
data = afile.read()
m.update(data)
return m.hexdigest()
################################################
if __name__=="__main__":
dir1 = sys.argv[1]
info={}
hashes = defaultdict(list)
for path, dirname, filenames in os.walk(dir1):
for filename in filenames:
md5 = md5checksum(os.path.join(path, filename))
info[str(path)+filename] = md5
hashes[md5] += [os.path.join(path, filename)]