如何在Python中计算文件的MD5校验和?


84

我已经在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

我的代码中缺少什么吗?

谢谢。


Answers:


205

关于您的错误以及代码中缺少的内容。m是未为getmd5()功能定义的名称。

不冒犯,我知道您是一个初学者,但是您的代码无处不在。让我们一一看待您的问题:)

首先,您没有hashlib.md5.hexdigest()正确使用方法。请参考Python Doc Library中有关hashlib函数的说明。为提供的字符串返回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 original_md5 == md5_returned:
    print "MD5 verified."
else:
    print "MD5 verification failed!."

请查看“ Python:生成文件的MD5校验和”一文。它详细说明了几种方法可以有效地实现它。

祝你好运。


1
哇。我感到很尴尬。我想我为自己所做的事情输入了错误的代码,并随之增加了很多错误。谢谢你的帮助。我虽然更习惯于批处理和lua。所以Python对我来说很挑剔。
user2344996 2013年

19
您还应该使用open(file_name,'rb')以二进制模式打开文件,否则当os执行换行/回车返回转换时,您可能会遇到问题。请参阅mail.python.org/pipermail/tutor/2004-January/027634.htmlstackoverflow.com/questions/3431825/…–
twobeers

4
如果您正在使用二进制文件,请确保您以“ b”模式正确读取了它,最后我使它可以按预期工作:hashlib.sha512(open(fn,'rb')。read())。hexdigest ()
Jammy Lee

9

在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

在Python 3.7及更低版本上:

with open("your_filename.png", "rb") as f:
    file_hash = hashlib.md5()
    chunk = f.read(8192)
    while chunk:
        file_hash.update(chunk)
        chunk = f.read(8192)

print(file_hash.hexdigest())

这样可以一次读取文件8192(或2十三)字节,而不是一次读取所有文件,f.read()从而减少了内存消耗。


考虑使用hashlib.blake2b而不是md5(只需在上面的代码段中替换md5blake2b)。它的加密安全性比MD5更快


0

您可以通过读取二进制数据并使用来计算文件的校验和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);
                
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.