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

如何在Python中计算文件的MD5校验和?,python,md5,md5sum,Python,Md5,Md5sum,我已经用Python编写了一些代码来检查文件中的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

我已经用Python编写了一些代码来检查文件中的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
#定义文件名
filename=“file.exe”
#从文件中获取MD5
def getmd5(文件名):
返回m.hexdigest()
md5=dict()
对于文件名中的fname:
md5[fname]=getmd5(fname)
#用于警告用户校验和是否通过或失败的If语句

如果md5=='>md5将转到这里,说明您的错误和代码中缺少的内容
m
是未为
getmd5()
函数定义的名称

无意冒犯,我知道你是个初学者,但你的代码到处都是。让我们逐一看看您的问题:)

首先,您没有正确使用
hashlib.md5.hexdigest()
方法。请参阅中有关hashlib函数的说明。为提供的字符串返回MD5的正确方法是执行以下操作:

>>> import hashlib
>>> hashlib.md5("filename.exe").hexdigest()
'2a53375ff139d9837e93a38a279d63e5'
>>> import hashlib
>>> hashlib.md5(open('filename.exe','rb').read()).hexdigest()
'd41d8cd98f00b204e9800998ecf8427e'
然而,这里有一个更大的问题。您正在根据文件名字符串计算MD5,实际上MD5是根据文件内容计算的。您基本上需要读取文件内容并通过MD5进行传输。我的下一个例子不是很有效,但类似这样:

>>> import hashlib
>>> hashlib.md5("filename.exe").hexdigest()
'2a53375ff139d9837e93a38a279d63e5'
>>> 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中,您可以

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()
一次性读取所有字节,以使用更少的内存



考虑使用而不是
md5
(只需在上述代码片段中将
md5
替换为
blake2b
)。它的加密安全性高于MD5。

您可以通过读取二进制数据并使用
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);
                

hashlib
方法也支持
mmap
模块,所以我经常使用

从hashlib导入md5
从mmap导入mmap,访问
路径=。。。
打开(路径)作为文件,mmap(file.fileno(),0,access=access\u READ)作为文件:
打印(md5(文件).hexdigest())
其中
path
是文件的路径

参考:

编辑:与普通读取方法进行比较

(似乎我没有足够的声誉来展示这个形象)

从hashlib导入md5
从mmap导入访问\u读取,mmap
从matplotlib.pyplot导入网格、图例、绘图、显示、紧密布局、xlabel、ylabel
从内存\u探查器导入内存\u使用情况
来自numpy import arange
def MemoryMap():
打开(路径)作为文件,mmap(file.fileno(),0,access=access\u READ)作为文件:
打印(md5(文件).hexdigest())
def PlainRead():
打开(路径“rb”)作为文件:
打印(md5(file.read()).hexdigest())
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
路径=。。。
y=内存使用率(内存映射,间隔=0.01)
绘图(arange(len(y))/100,y,label='mmap')
y=内存使用率(纯读,间隔=0.01)
绘图(arange(len(y))/100,y,label='read')
ylabel('内存使用(MiB)')
xlabel(“时间”)
图例()
网格()
紧凑的布局()
show()

path
是指向3.77GiB csv文件的路径。

Wow。我觉得很尴尬。我想我在做什么的时候输入了错误的代码,并在代码中添加了很多错误。谢谢你的帮助。我虽然更习惯于批处理和lua。所以Python对我来说很挑剔。你也应该用open(file_name,'rb')以二进制模式打开文件,否则当操作系统进行换行/回车转换时,你可能会遇到问题。请参阅,如果您正在处理一个二进制文件,请确保您使用“b”模式正确读取该文件,最后我使用以下命令使其正常工作:hashlib.sha512(open(fn,'rb').read()).hexdigest()是否将整个文件读取到内存中?那么为什么不直接执行
hashlib.md5(file.read()).hexdigest()
@Boris从图中可以看出,我认为
mmap
方法交替读取和处理,但使用后内存似乎没有释放。