Python에서 파일의 MD5 체크섬을 어떻게 계산합니까?


84

파일에서 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 Doc Library의 hashlib 함수에 대한 설명을 참조하십시오 . 제공된 문자열에 대해 MD5를 반환하는 올바른 방법 은 다음과 같이하는 것입니다.

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

그러나 여기에 더 큰 문제가 있습니다. 당신은에 MD5를 계산하는 파일 이름 문자열 파일을 기준으로 계산됩니다 현실 MD5에, 내용 . 기본적으로 파일 내용을 읽고 MD5를 통해 파이프해야합니다. 다음 예제는 매우 효율적이 아니지만 다음과 같습니다.

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

분명히 알 수 있듯이 두 번째 MD5 해시는 첫 번째 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!."

포스트를보고하십시오 파일의 MD5 체크섬을 생성 : 파이썬 . 효율적으로 달성 할 수있는 몇 가지 방법을 자세히 설명합니다.

행운을 빌어 요.


1
와. 너무 부끄러워요. 내가하던 일에 대해 잘못된 코드를 입력하고 그와 함께 많은 실수를 추가 한 것 같습니다. 당신의 도움을 주셔서 감사합니다. 나는 배치와 루아에 더 익숙하지만. 그래서 파이썬은 저에게 까다 롭습니다.
user2344996

19
또한 open (file_name, 'rb')을 사용하여 바이너리 모드로 파일을 열어야합니다. 그렇지 않으면 os가 개행 / 캐리지 반환 변환을 수행 할 때 문제가 발생할 수 있습니다. 참조 mail.python.org/pipermail/tutor/2004-January/027634.htmlstackoverflow.com/questions/3431825/...
twobeers

4
바이너리 파일에서 작업하는 경우 'b'모드로 올바르게 읽었는지 확인하고 마지막으로 다음과 같이 예상대로 작동하도록합니다. hashlib.sha512 (open (fn, 'rb'). read ()). hexdigest ()
Jammy가 리

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(만 교체 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);
                
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.