Làm cách nào để tính toán tổng kiểm tra MD5 của một tệp bằng Python?


84

Tôi đã tạo một mã bằng Python để kiểm tra MD5 trong một tệp và đảm bảo MD5 khớp với MD5 của bản gốc.

Đây là những gì tôi đã phát triển:

#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

Nhưng bất cứ khi nào tôi chạy mã, tôi gặp lỗi sau:

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

Có điều gì tôi thiếu trong mã của mình không?

Cảm ơn.


Câu trả lời:


205

Liên quan đến lỗi của bạn và những gì còn thiếu trong mã của bạn. mlà một tên không được xác định cho getmd5()chức năng.

Không xúc phạm, tôi biết bạn là người mới bắt đầu, nhưng mã của bạn ở khắp nơi. Hãy xem xét các vấn đề của bạn từng cái một :)

Đầu tiên, bạn không sử dụng hashlib.md5.hexdigest()đúng phương pháp. Vui lòng tham khảo giải thích về các hàm băm trong Thư viện Tài liệu Python . Cách chính xác để trả về MD5 cho chuỗi đã cung cấp là làm như sau:

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

Tuy nhiên, bạn có một vấn đề lớn hơn ở đây. Bạn đang tính MD5 trên một chuỗi tên tệp , trong thực tế, MD5 được tính dựa trên nội dung tệp . Về cơ bản, bạn sẽ cần đọc nội dung tệp và chuyển nó qua MD5. Ví dụ tiếp theo của tôi không hiệu quả lắm, nhưng giống như thế này:

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

Như bạn có thể thấy rõ ràng băm MD5 thứ hai hoàn toàn khác với băm đầu tiên. Lý do là chúng ta đang đẩy nội dung của tệp qua, không chỉ tên tệp.

Một giải pháp đơn giản có thể là một cái gì đó như thế:

# 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!."

Vui lòng xem bài đăng Python: Tạo tổng kiểm tra MD5 của một tệp . Nó giải thích chi tiết một số cách có thể đạt được hiệu quả.

May mắn nhất.


1
Chà. Tôi cảm thấy rất xấu hổ. Tôi đoán rằng tôi đã đặt sai mã cho những gì tôi đang làm và thêm rất nhiều lỗi cùng với nó. Cảm ơn bạn đã giúp đỡ. Tôi mặc dù được sử dụng nhiều hơn để hàng loạt và lua. Vì vậy, Python rất kén chọn đối với tôi.
dùng2344996

19
Bạn cũng nên mở tệp ở chế độ nhị phân với mở (tên_tệp, 'rb'), nếu không bạn có thể gặp sự cố khi hệ điều hành thực hiện chuyển đổi dòng mới / xuống dòng. Xem mail.python.org/pipermail/tutor/2004-January/027634.htmlstackoverflow.com/questions/3431825/…
twobeers

4
Nếu bạn đang làm việc với tệp nhị phân, hãy đảm bảo rằng bạn đọc nó chính xác với chế độ 'b', cuối cùng tôi làm cho nó hoạt động như mong đợi với điều này: hashlib.sha512 (open (fn, 'rb'). Read ()). Hexdigest ()
Jammy Lee

9

Trong Python 3.8+, bạn có thể làm

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

Trên Python 3.7 trở xuống:

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

Thao tác này đọc tệp 8192 (hoặc 2¹³) byte cùng một lúc thay vì tất cả cùng một lúc f.read()để sử dụng ít bộ nhớ hơn.


Cân nhắc sử dụng hashlib.blake2bthay vì md5(chỉ thay thế md5bằng blake2btrong đoạn mã trên). Nó an toàn bằng mật mã và nhanh hơn MD5.


0

Bạn có thể tính tổng tổng của một tệp bằng cách đọc dữ liệu nhị phân và sử dụng hashlib.md5().hexdigest(). Một hàm để thực hiện việc này sẽ giống như sau:

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);
                
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.