一、使用python自带的hash库hashlib
对于大文件,不能简单的一次载入内存,需要对文件分片不断的update完成(代码中如果文件超过100M,就需要分片了)。具体代码如下:
1 import os 2 import sys 3 import hashlib 4 5 _FILE_SLIM = (100*1024*1024) # 100MB 6 7 8 def file_md5(filename): 9 calltimes = 0 10 hmd5 = hashlib.md5() 11 fp = open(filename,"rb") 12 f_size = os.stat(filename).st_size 13 if f_size>_FILE_SLIM: 14 while(f_size>_FILE_SLIM): 15 hmd5.update(fp.read(_FILE_SLIM)) 16 f_size/=_FILE_SLIM 17 calltimes += 1 #delete 18 if(f_size>0) and (f_size<=_FILE_SLIM): 19 hmd5.update(fp.read()) 20 else: 21 hmd5.update(fp.read()) 22 23 return (hmd5.hexdigest(),calltimes) 24 25 26 if __name__ == '__main__': 27 if len(sys.argv) == 2: 28 filepath = os.path.abspath(sys.argv[1]) 29 (hvalue,ctimes) = file_md5(filepath) 30 print(hvalue) 31 32
二、测试
从meizu官网上下了个固件更新包,检测测试了下,没有问题。
测试执行:python calc_file_md5.py filename
三、更新下代码
可以计算hashlib中所有的所有的hash值,包括:md5, sha1, sha224, sha256, sha384, sha512.
主要思路是:采用字典结构来存储hash函数,达到泛型。
代码如下:
1 # coding=gbk 2 __doc__ = ''' 3 filehash.py md5/sha1/sha224/sha256/sha384/sha512 targetfile 4 argc must be equal to 3 5 ''' 6 7 import os 8 import hashlib 9 10 __supported_hashfunc = {'md5':hashlib.md5, 'sha1':hashlib.sha1, 'sha224':hashlib.sha224, 'sha256':hashlib.sha256, 'sha384':hashlib.sha384, 'sha512':hashlib.sha512} 11 __FILE_SLIM = (100*1024*1024) # 100MB 12 13 def filehash(hfunc,filename): 14 hobj = hfunc() 15 fp = open(filename,"rb") 16 f_size = os.stat(filename).st_size 17 while(f_size > __FILE_SLIM): 18 hobj.update(fp.read(__FILE_SLIM)) 19 f_size /= __FILE_SLIM 20 #print("o.o") 21 if(f_size>0) and (f_size <= __FILE_SLIM): 22 hobj.update(fp.read()) 23 fp.close() 24 return hobj.hexdigest() 25 26 def main(): 27 import sys 28 if len(sys.argv) == 3: 29 try: 30 hfunc = __supported_hashfunc[sys.argv[1].lower()] 31 #print(sys.argv[1]) 32 filepath = os.path.abspath(sys.argv[2]) 33 hvalue = filehash(hfunc,filepath) 34 print(sys.argv[1],hvalue,sep=':') 35 except KeyError: 36 print('''input cmd:"%s" is error'''%sys.argv[1]) 37 else: 38 print(__doc__) 39 if __name__ == '__main__': 40 main() 41