Как рассчитать контрольную сумму MD5 файла в Python?


90

Я сделал код на 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

Что мне не хватает в моем коде?

Благодарю.


Ответы:


210

Что касается вашей ошибки и того, чего не хватает в вашем коде. mэто имя, которое не определено для getmd5()функции.

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

Во-первых, вы hashlib.md5.hexdigest()неправильно используете метод. Пожалуйста, обратитесь к объяснению функций hashlib в Python Doc Library . Правильный способ вернуть 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 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 ()
Джемми Ли

13

В 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.


-2

Вы можете рассчитать контрольную сумму файла, прочитав двоичные данные и используя 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.