Як розрахувати контрольну суму MD5 файлу в Python?


86

Я створив код на 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

Чи щось мені не вистачає у моєму коді?

Дякую.


Відповіді:


206

Стосовно вашої помилки та того, чого не вистачає у коді. mце ім'я, яке не визначено для getmd5()функції.

Не ображайтесь, я знаю, що ви новачок, але ваш код повсюдно. Давайте розглянемо ваші питання по одному :)

По-перше, ви неправильно використовуєте hashlib.md5.hexdigest()метод. Будь ласка, зверніться до пояснення щодо функцій hashlib у бібліотеці Python Doc . Правильний спосіб повернути 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
Ого. Мені так соромно. Напевно, я поставив неправильний код того, що робив, і додав разом з ним багато помилок. Спасибі за вашу допомогу. Я хоча більше звик до партії та луа. Тож Python для мене вибагливий.
user2344996 02

20
Вам також слід відкрити файл у двійковому режимі за допомогою open (ім'я_файла, 'rb'), інакше у вас можуть виникнути проблеми, коли ОС повертає перетворення нового рядка / каретки. Див mail.python.org/pipermail/tutor/2004-January/027634.html і stackoverflow.com/questions/3431825 / ...
twobeers

4
Якщо ви працюєте з двійковим файлом, переконайтеся, що ви його правильно прочитали в режимі "b", нарешті, я змушую його працювати так, як очікувалося: hashlib.sha512 (open (fn, 'rb'). Read ()). Hexdigest ()
Jammy Lee

10

У 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(просто замініть md5на blake2bу наведеному вище фрагменті). Це криптографічно безпечно і швидше, ніж 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);
                
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.