PythonでファイルのMD5チェックサムを計算するにはどうすればよいですか?


84

ファイル内のMD5をチェックし、MD5が元のMD5と一致することを確認するコードをPythonで作成しました。

これが私が開発したものです:

#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

コードに欠けているものはありますか?

ありがとう。


回答:


205

あなたのエラーとあなたのコードに欠けているものに関して。関数mに対して定義されていない名前getmd5()です。

違法ではありません。あなたが初心者であることは知っていますが、コードはいたるところにあります。あなたの問題を一つずつ見てみましょう:)

まず、hashlib.md5.hexdigest()メソッドを正しく使用していません。Python DocLibraryのhashlib関数の説明を参照してください。指定された文字列に対してMD5を返す正しい方法は、次のようにすることです。

>>> import hashlib
>>> hashlib.md5("filename.exe").hexdigest()
'2a53375ff139d9837e93a38a279d63e5'

ただし、ここではさらに大きな問題があります。あなたは上のMD5を計算しているファイル名の文字列ファイルに基づいて計算される現実MD5で、内容。基本的にファイルの内容を読み取り、MD5を介してパイプする必要があります。次の例はあまり効率的ではありませんが、次のようなものです。

>>> import hashlib
>>> hashlib.md5(open('filename.exe','rb').read()).hexdigest()
'd41d8cd98f00b204e9800998ecf8427e'

ご覧のとおり、2番目の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.htmlおよびstackoverflow.com/questions/3431825/…を
twobeers 2013年

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())

これによりf.read()、使用するメモリを減らすために、ファイルを一度にすべてではなく、一度に8192(または2¹³)バイト読み取ります。


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);
                
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.