搜索并打印具有相同 MD5 的文件
Search and print files that have the same MD5
我正在编写一个 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 校验和的元素。
您需要跟踪每个散列的冲突文件名(即从散列到具有该散列的文件的文件名的映射)。最简单的方法是使用 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)]
你快到了。关键是你必须反转字典的结构:为了方便地搜索具有相同校验和的文件,你可以使用 MD5 和作为 key,并且 具有该校验和作为值的路径列表:
{'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
几个注意事项:
- 你的 shebang 是错误的。它应该以
#!/
开头,而不是 #/
- 您的
md5checksums()
函数中的缩进错误。缩进在 Python 中非常重要,请务必密切注意它。
- 使用
os.path.join
加入文件路径。
- 尝试遵循 PEP8 style guide,它使您的代码更具可读性
我正在编写一个 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 校验和的元素。
您需要跟踪每个散列的冲突文件名(即从散列到具有该散列的文件的文件名的映射)。最简单的方法是使用 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)]
你快到了。关键是你必须反转字典的结构:为了方便地搜索具有相同校验和的文件,你可以使用 MD5 和作为 key,并且 具有该校验和作为值的路径列表:
{'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
几个注意事项:
- 你的 shebang 是错误的。它应该以
#!/
开头,而不是#/
- 您的
md5checksums()
函数中的缩进错误。缩进在 Python 中非常重要,请务必密切注意它。 - 使用
os.path.join
加入文件路径。 - 尝试遵循 PEP8 style guide,它使您的代码更具可读性