我在python中创建了一个代码,用于检查文件中的md5并确保md5与原始文件匹配。以下是我开发的内容:
#Defines filename
filename = "file.exe"
#Gets MD5 from file
def getmd5(filename):
return m.hexdigest()
md5 = dict()
for fname in filename:
md5[fname] = getmd5(fname)
#If statement for alerting the user whether the checksum passed or failed
if md5 == '>md5 will go here<':
print("MD5 Checksum passed. You may now close this window")
input ("press enter")
else:
print("MD5 Checksum failed. Incorrect MD5 in file 'filename'. Please download a new copy")
input("press enter")
exit
但每当我运行代码时,我都会得到以下结果:
Traceback (most recent call last):
File "C:\Users\Username\md5check.py", line 13, in <module>
md5[fname] = getmd5(fname)
File "C:\Users\Username\md5check.py, line 9, in getmd5
return m.hexdigest()
NameError: global name 'm' is not defined
我的代码中是否有任何遗漏?
答案 0 :(得分:132)
关于您的错误以及代码中缺少的内容。 m是未为getmd5()函数定义的名称。没有冒犯,我知道你是初学者,但你的代码到处都是。让我们一个一个地看看你的问题:)首先,你没有正确使用hashlib.md5.hexdigest()方法。请查找有关haslib函数Python Doc Library的说明。为提供的字符串返回md5的正确方法是执行以下操作:
>>> import hashlib
>>> hashlib.md5("filename.exe").hexdigest()
'2a53375ff139d9837e93a38a279d63e5'
但是,这里有更大的问题。您正在文件名字符串上计算MD5,其中实际上MD5是根据文件内容计算的。您将需要基本上读取文件内容并通过md5管道它。我的下一个例子不是很有效,但是类似的东西:
>>> import hashlib
>>> hashlib.md5(open('filename.exe','rb').read()).hexdigest()
'd41d8cd98f00b204e9800998ecf8427e'
您可以清楚地看到第二个MD5哈希与第一个完全不同。原因是我们正在推送文件的内容,而不仅仅是文件名。一个简单的解决方案可能是这样的:
# Import hashlib library (md5 method is part of it)
import hashlib
# File to check
file_name = 'filename.exe'
# Correct original md5 goes here
original_md5 = '5d41402abc4b2a76b9719d911017c592'
# Open,close, read file and calculate MD5 on its contents
with open(file_name) as file_to_check:
# read contents of the file
data = file_to_check.read()
# pipe contents of the file through
md5_returned = hashlib.md5(data).hexdigest()
# Finally compare original MD5 with freshly calculated
if orginal_md5 == md5_returned:
print "MD5 verified."
else:
print "MD5 verification failed!."
请查看帖子 Python: Generating a MD5 checksum of a file ,它详细解释了如何有效实现这一目标。
祝你好运。
答案 1 :(得分:0)
在Python 3.8+中,您可以
import hashlib
with open("your_filename.png", "rb") as f:
file_hash = hashlib.md5()
while chunk := f.read(8192):
file_hash.update(chunk)
print(file_hash.digest())
print(file_hash.hexdigest()) # to get a printable str instead of bytes
请考虑使用hashlib.blake2b
而不是md5
(只需将以上代码段中的md5
替换为blake2b
)。与MD5相比,它是加密安全的,faster。
答案 2 :(得分:0)
hashlib
方法也支持 mmap
模块,所以我经常使用
from hashlib import md5
from mmap import mmap, ACCESS_READ
path = ...
with open(path) as file, mmap(file.fileno(), 0, access=ACCESS_READ) as file:
print(md5(file).hexdigest())
其中 path
是文件的路径。
参考:https://docs.python.org/library/mmap.html#mmap.mmap
编辑:与普通读取方法的比较。
(似乎我没有足够的声誉来显示图像)
from hashlib import md5
from mmap import ACCESS_READ, mmap
from matplotlib.pyplot import grid, legend, plot, show, tight_layout, xlabel, ylabel
from memory_profiler import memory_usage
from numpy import arange
def MemoryMap():
with open(path) as file, mmap(file.fileno(), 0, access=ACCESS_READ) as file:
print(md5(file).hexdigest())
def PlainRead():
with open(path, 'rb') as file:
print(md5(file.read()).hexdigest())
if __name__ == '__main__':
path = ...
y = memory_usage(MemoryMap, interval=0.01)
plot(arange(len(y)) / 100, y, label='mmap')
y = memory_usage(PlainRead, interval=0.01)
plot(arange(len(y)) / 100, y, label='read')
ylabel('Memory Usage (MiB)')
xlabel('Time (s)')
legend()
grid()
tight_layout()
show()
path
是 3.77GiB csv 文件的路径。
答案 3 :(得分:-2)
您可以通过读取二进制数据并使用hashlib.md5().hexdigest()
来计算文件的校验和。一个执行此操作的功能如下所示:
def File_Checksum_Dis(dirname):
if not os.path.exists(dirname):
print(dirname+" directory is not existing");
for fname in os.listdir(dirname):
if not fname.endswith('~'):
fnaav = os.path.join(dirname, fname);
fd = open(fnaav, 'rb');
data = fd.read();
fd.close();
print("-"*70);
print("File Name is: ",fname);
print(hashlib.md5(data).hexdigest())
print("-"*70);