itsource

파일의 MD5 체크섬 생성

mycopycode 2022. 9. 5. 23:16
반응형

파일의 MD5 체크섬 생성

Python에서 파일 목록의 MD5 체크섬을 생성하고 확인하는 간단한 방법이 있습니까?(작성 중인 작은 프로그램이 있는데 파일의 체크섬을 확인하고 싶습니다.)

hashlib.md5()를 사용할 수 있습니다.

파일 전체를 메모리에 저장할 수 없는 경우가 있습니다.이 경우 4096바이트의 청크를 순차적으로 읽어서md5방법:

import hashlib
def md5(fname):
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

주의: hash_md5.hexdigest()digest에 대한 16진수 문자열 표현을 반환합니다(패킹된 바이트 사용만 필요한 경우).return hash_md5.digest()변환하지 않아도 됩니다.

비효율적인 기억력의 방법이 있다.

단일 파일:

import hashlib
def file_as_bytes(file):
    with file:
        return file.read()

print hashlib.md5(file_as_bytes(open(full_path, 'rb'))).hexdigest()

파일 목록:

[(fname, hashlib.md5(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

, MD5는 파손된 것으로 알려져 있기 때문에 취약성 분석이 매우 까다로울 수 있으므로 어떤 목적으로도 사용해서는 안 됩니다.또, 향후, 시큐러티 문제에 대해서 코드를 사용할 가능성이 있는 경우는, 분석이 불가능할 가능성이 있습니다.IMHO, 그것은 라이브러리에서 완전히 제거되어야 합니다. 그래서 그것을 사용하는 모든 사람들은 강제로 업데이트를 해야 합니다.그 대신 다음과 같은 작업을 수행해야 합니다.

[(fname, hashlib.sha256(file_as_bytes(open(fname, 'rb'))).digest()) for fname in fnamelst]

128비트 상당의 다이제스트만 필요한 경우.digest()[:16].

그러면 파일 이름과 해시가 포함된 각 튜플 목록이 나타납니다.

MD5의 사용에 대해 다시 한 번 강하게 의문을 제기합니다.적어도 SHA1을 사용해야 하며, SHA1에서 최근 발견된 결함을 고려하면 그것조차도 사용할 수 없습니다.MD5를 '암호화' 목적으로 사용하지 않는 한 괜찮다고 생각하는 사람도 있습니다.단, 처음에 예상했던 것보다 범위가 넓어지는 경향이 있으며, 일반적인 취약성 분석에서 완전히 결함이 발견될 수 있습니다.올바른 알고리즘을 사용하는 습관을 들이는 것이 가장 좋습니다.그냥 다른 글자를 타이핑하는 거야그렇게 어렵지 않다.

다음은 보다 복잡하지만 메모리 효율이 뛰어난 방법입니다.

import hashlib

def hash_bytestr_iter(bytesiter, hasher, ashexstr=False):
    for block in bytesiter:
        hasher.update(block)
    return hasher.hexdigest() if ashexstr else hasher.digest()

def file_as_blockiter(afile, blocksize=65536):
    with afile:
        block = afile.read(blocksize)
        while len(block) > 0:
            yield block
            block = afile.read(blocksize)


[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.md5()))
    for fname in fnamelst]

MD5는 고장났기 때문에 더 이상 사용할 수 없습니다.

[(fname, hash_bytestr_iter(file_as_blockiter(open(fname, 'rb')), hashlib.sha256()))
    for fname in fnamelst]

다시 한 번 말씀드리지만[:16]호출 후hash_bytestr_iter(...)128비트치의 다이제스트만을 필요로 하는 경우.

저는 분명히 근본적으로 새로운 것을 추가하지는 않았지만, 코멘트 상태에 이르기 전에 이 답변을 추가했습니다.그리고 코드 영역은 상황을 더 명확하게 합니다.어쨌든, 특히 Omnifarious의 답변에서 @Nemo의 질문에 답하기 위해서입니다.

우연히 체크섬에 대해 조금 생각하고 있었는데(구체적으로 블록 사이즈에 대한 제안을 찾고 있습니다), 이 방법이 생각보다 빠르다는 것을 알게 되었습니다.가장 빠른 선택(단, 매우 일반적인)timeit.timeit또는/usr/bin/time약 11MB의 파일을 체크섬하는 여러 가지 방법에서 발생합니다.

$ ./sum_methods.py
crc32_mmap(filename) 0.0241742134094
crc32_read(filename) 0.0219960212708
subprocess.check_output(['cksum', filename]) 0.0553209781647
md5sum_mmap(filename) 0.0286180973053
md5sum_read(filename) 0.0311000347137
subprocess.check_output(['md5sum', filename]) 0.0332629680634
$ time md5sum /tmp/test.data.300k
d3fe3d5d4c2460b5daacc30c6efbc77f  /tmp/test.data.300k

real    0m0.043s
user    0m0.032s
sys     0m0.010s
$ stat -c '%s' /tmp/test.data.300k
11890400

따라서 Python과 /usr/bin/md5sum 모두 11MB 파일에 약 30ms가 소요됩니다.관련 정보md5sum기능하다md5sum_read위 목록의)는 Omnifarious의 경우와 매우 유사합니다.

import hashlib
def md5sum(filename, blocksize=65536):
    hash = hashlib.md5()
    with open(filename, "rb") as f:
        for block in iter(lambda: f.read(blocksize), b""):
            hash.update(block)
    return hash.hexdigest()

인정합니다.이러한 것은 1회 실행에서mmap최소 수십 번의 주행이 이루어지면 항상 조금 더 빠릅니다.) 그리고 내 것은 보통 여분의 주행이 있습니다.f.read(blocksize)버퍼가 소진된 후, 하지만 이는 합리적으로 반복 가능하며md5sum명령줄에서 Python 구현보다 빠를 필요는 없습니다.

편집: 오래 걸려서 죄송합니다.오랫동안 이걸 못 봤지만, @EdRandall의 질문에 답하기 위해 Adler32 구현을 적어두겠습니다.하지만, 저는 그것에 대한 벤치마크를 실행하지 않았습니다.기본적으로는 CRC32와 동일합니다.초기, 업데이트 및 다이제스트콜 대신 모든 것이 CRC32의zlib.adler32()호출:

import zlib
def adler32sum(filename, blocksize=65536):
    checksum = zlib.adler32("")
    with open(filename, "rb") as f:
        for block in iter(lambda: f.read(blocksize), b""):
            checksum = zlib.adler32(block, checksum)
    return checksum & 0xffffffff

Adler의 합계는 실제로 0에서 시작할 때와 다음 시간 동안 합계가 다르므로 빈 문자열로 시작해야 합니다."",어느 것이1-- CRC는 다음으로 시작할 수 있습니다.0대신.AND-ing은 32비트 부호 없는 정수로 만들기 위해 필요하며 Python 버전 전체에서 동일한 값을 반환합니다.

Python 3.8+에서는 할당 연산자를 사용할 수 있습니다. :=(와 함께)는 다음과 같습니다.

import hashlib
with open("your_filename.txt", "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

대신 을 사용하는 것을 검토하다md5(교환만 하면 됩니다)md5와 함께blake2b를 참조해 주세요).암호화로 안전하고 MD5보다 빠릅니다.

hashlib.md5(pathlib.Path('path/to/file').read_bytes()).hexdigest()

를 사용하면 macOS/Linux 및 Windows용 호출에만 사용하고 출력에서 다이제스트만 추출할 수 있습니다.

설치:

pip install simple-file-checksum

사용방법:

>>> from simple_file_checksum import get_checksum
>>> get_checksum("path/to/file.txt")
'9e107d9d372bb6826bd81d3542a419d6'
>>> get_checksum("path/to/file.txt", algorithm="MD5")
'9e107d9d372bb6826bd81d3542a419d6'

SHA1,SHA256,SHA384 , , , , 입니다.SHA512알고리즘도 지원됩니다.


1 공개:저는 의 저자입니다.

file_path

import hashlib
def getMd5(file_path):
    m = hashlib.md5()
    with open(file_path,'rb') as f:
        lines = f.read()
        m.update(lines)
    md5code = m.hexdigest()
    return md5code

언급URL : https://stackoverflow.com/questions/3431825/generating-an-md5-checksum-of-a-file

반응형