2013-06-11 9 views
1

오늘 사용 가능한 모든 hashlib 알고리즘 (md5, sha1 .....)의 체크섬 파일에 간단한 스크립트로 작업했습니다. 파이썬 2로 작성하고 디버깅했지만 파이썬 3에 이식하기로 결정했을 때 작동하지 않습니다. 재미있는 점은 작은 파일에서는 작동하지만 큰 파일에서는 작동하지 않는다는 것입니다. 나는 파일을 버퍼링하는 방식에 문제가 있다고 생각했지만 오류 메시지는 내가 hexdigest (내가 생각하는) 방식과 관련이 있다고 생각하게 만든다. 여기 내 전체 스크립트의 복사본이있다. 자유롭게 복사하여 사용하십시오. 문제가 무엇인지 파악하는 데 도움이됩니다. 내가 구글Python2에서 작동하지만 Python 3 (hashlib)에서 작동하지 않는 스크립트

,하지만 수 : 250 메가 바이트 파일을 checksuming 때 내가 오류는 "잘못된 연속 바이트 'UTF-8'코덱의 위치는 10 바이트 0xf3를 디코딩 할 수 없습니다"

입니다 그것을 고치는 어떤 것도 찾지 못한다. 또한 최적화 방법을 더 잘 알고 있다면 알려 주시기 바랍니다. 내 주요 목표는 파이썬으로 작업 100 %를 만들 3. 감사 여기
#!/usr/local/bin/python33 
import hashlib 
import argparse 

def hashFile(algorithm = "md5", filepaths=[], blockSize=4096): 
    algorithmType = getattr(hashlib, algorithm.lower())() #Default: hashlib.md5() 
    #Open file and extract data in chunks 
    for path in filepaths: 
     try: 
      with open(path) as f: 
       while True: 
        dataChunk = f.read(blockSize) 
        if not dataChunk: 
         break 
        algorithmType.update(dataChunk.encode()) 
       yield algorithmType.hexdigest() 
     except Exception as e: 
      print (e) 

def main(): 
    #DEFINE ARGUMENTS 
    parser = argparse.ArgumentParser() 
    parser.add_argument('filepaths', nargs="+", help='Specified the path of the file(s) to hash') 
    parser.add_argument('-a', '--algorithm', action='store', dest='algorithm', default="md5", 
         help='Specifies what algorithm to use ("md5", "sha1", "sha224", "sha384", "sha512")') 
    arguments = parser.parse_args() 
    algo = arguments.algorithm 
    if algo.lower() in ("md5", "sha1", "sha224", "sha384", "sha512"): 

하는 것입니다 파이썬 2에서 작동하는 코드가, 난 그냥 위를 modigy하지 않고 당신이 그것을 사용하고자하는 경우에 넣어 것입니다 .

#!/usr/bin/python 
import hashlib 
import argparse 

def hashFile(algorithm = "md5", filepaths=[], blockSize=4096): 
    ''' 
    Hashes a file. In oder to reduce the amount of memory used by the script, it hashes the file in chunks instead of putting 
    the whole file in memory 
    ''' 
    algorithmType = hashlib.new(algorithm) #getattr(hashlib, algorithm.lower())() #Default: hashlib.md5() 
    #Open file and extract data in chunks 
    for path in filepaths: 
     try: 
      with open(path, mode = 'rb') as f: 
       while True: 
        dataChunk = f.read(blockSize) 
        if not dataChunk: 
         break 
        algorithmType.update(dataChunk) 
       yield algorithmType.hexdigest() 
     except Exception as e: 
      print e 

def main(): 
    #DEFINE ARGUMENTS 
    parser = argparse.ArgumentParser() 
    parser.add_argument('filepaths', nargs="+", help='Specified the path of the file(s) to hash') 
    parser.add_argument('-a', '--algorithm', action='store', dest='algorithm', default="md5", 
         help='Specifies what algorithm to use ("md5", "sha1", "sha224", "sha384", "sha512")') 
    arguments = parser.parse_args() 
    #Call generator function to yield hash value 
    algo = arguments.algorithm 
    if algo.lower() in ("md5", "sha1", "sha224", "sha384", "sha512"): 
     for hashValue in hashFile(algo, arguments.filepaths): 
      print hashValue 
    else: 
     print "Algorithm {0} is not available in this script".format(algorithm) 

if __name__ == "__main__": 
    main() 

답변

1

내가 파이썬 3에서 시도하지 않은,하지만 난 이진 파일에 대한 파이썬 2.7.5에서 같은 오류가 발생합니다 (유일한 차이점은 광산 아스키 코덱 점이다).

with open(path, 'rb') as f: 
    while True: 
     dataChunk = f.read(blockSize) 
     if not dataChunk: 
      break 
     algorithmType.update(dataChunk) 
    yield algorithmType.hexdigest() 

이 외에도에서, 내가 getattr 대신 방법 hashlib.new을 사용하십시오, 인수가 유효한 경우 hashlib.algorithms_available 확인하는 대신 데이터 청크를 인코딩의 바이너리 (binary) 모드로 직접 파일을 엽니 다.

+0

감사합니다. 3.2 이후에서만 사용할 수 있고 python2에서는 사용할 수 없으므로 hashlib.algorithms_available을 피할 것입니다. 그러나 hashlib.new는 분명히 깨끗해 보입니다. – JohnnyLoo

+0

BTW 내가 언급 한 오류가 있는데, "dataChunk"를 업데이트 할 때 .encode() 부분을 제거하여 해결했습니다. 내가 추가 한 두 번째 스크립트는 당신을 위해 작동해야합니다. – JohnnyLoo

+0

@JuanCarlos 오류는 발생하지 않지만 바이너리 모드로 파일을 열지 않으면 잘못된 md5sum입니다. –