2016-11-04 3 views
2

이 질문은 이미이 사이트에서 여러 번 묻고 답해 왔지만 다소 모호한 이유로 아무도 비교적 간단한 (제 의견으로는) 간결하고 아마 더 많은 것을 생각해 냈습니다 우아한 솔루션. 아마 해결책이 실제로 나쁘기 때문에, 그러나 그것이 내가 알아 내려고 노력하고있는 것입니다. 그것이 나쁘다면, 어떻게 그리고 왜 알고 싶습니다. 우리가 메모리에 전체 파일을로드하지 않으려는 그래서 우리는 반복자 및 람다 함수의 도움으로 덩어리를 읽을 -파이썬에서 파일의 체크섬 생성하기

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

그것은 이해할가 : 가장 인기있는 답변 하나는이이었다. 좋고 간단합니다.

def md5sum(fname): 
    md5 = hashlib.md5() 
    with open(fname, 'rb') as f: 
    for chunk in f: 
     md5.update(chunk) 
    return md5.hexdigest() 

편리하게, 열린 파일 핸들을 반복하는 것은 우리에게 그 라인의 순서를 제공합니다, 그래서 우리는 'B'를 사용할 수 있습니다 그러나 아마도 우리가 같이 md5sum이 함수를 정의하여 더 간단하게이 작업을 수행 할 수는 다음과 접두사는 open(fname, 'rb')으로 바이트 개체를 반복 처리합니다. 그 일을 잘못한 것은 무엇입니까?

+3

아마 어떤 종류의 파일을 다루고 있는지, 특히 실제로 ASCII 파일 이건 이진 파일 이건간에 상관 없습니다. 원래 버전은 청크 크기를보다 잘 제어 할 수 있지만 버전은 줄 바꿈이 예상되는 곳에 있습니다. 또한 대용량 파일을 처리하기 위해 한 번에 4K의 데이터 만 사용하지는 않지만 "덩어리"에 상당한 오버 헤드가 없는지 확인하기 위해 최소 100K는 사용합니다. 한 번은 zip 모듈에 대한 경험이 있었고 100K는 오늘날 아무것도 아닙니다. –

+0

@ Dr.V 나는 당신이 말하는 거의 모든 것에 동의하지만, 내가 볼 수있는 한, 그것은 모든 종류의 파일에 대해 잘 작동한다. – weeCoder

+1

@weeCoder'\ x0a' 바이트를 포함하지 않는 거대한 파일을 만들어보십시오.'for chunk in f'는 전체 파일을 메모리로 읽어들이는'chunk = f.read()'로 저하됩니다 . – Bakuriu

답변

2

Dr. V가 언급 한 내용은 정확합니다.

for chunk in f:을 사용하면 b'\n '== b'\x0A'으로 끝나는 청크에서 작동합니다. 따라서 청크 크기는 이고 텍스트 파일의 경우에는으로 작고 일반적인 이진 파일의 경우에는 예측할 수 없습니다. 이진 파일의 경우 인 경우0A 바이트가 포함되지 않을 수 있습니다. 그런 일이 발생하면 for chunk in f:은 전체 파일을 단일 청크로 읽습니다.

4k 청크 크기는 괜찮지 만 64k 또는 128k 청크 크기로 시도하면 속도가 향상되는지 확인할 수 있습니다. 간단한 데이터 복사 테스트 (dd 사용)에서는 큰 청크 크기를 사용할 때 거의 이점이 없었습니다. 현대 OS가 파일 버퍼링을 잘 수행하고 있다는 것을 명심하십시오. & 캐싱. OTOH, 오히려 오래된 32 비트 단일 코어 머신을 돌리고 있습니다.

큰 파일을 해시하는 주제에서 OpenSSL 암호화 라이브러리를 사용하여 대용량 파일에 SHA256 해시를 수행하는 a program I wrote에 관심이있을 수 있습니다. 이 프로그램의 특징은 재개 가능하다는 것입니다. 언제든지 중지 할 수 있으며 다시 시작할 때 해시 프로세스가 계속됩니다.

here's onehashlib을 사용하여 파일의 MD5 및 SHA256 해시를 동시에 계산합니다.

관련 문제