Python常人笔记 -- 文件校验

    添加时间:2013-5-10 点击量:

        好久没有写漫笔了,正好这两天可以休整一下,借此机会总结下比来应用python的小领会。


        小我领会文件校验鄙人载文件时应用较多,在linux下最简单的实现体式格式就是:



    1 ¥ md5sum filename
    
    2 21c7ee192e64569ce43cfb869bdb2755 filename


         当然在python傍边也有对应的模块可以实现此功能,在python2.5之前可以应用 md5 模块,然则在python2.5今后就推荐应用 hashlib 来庖代 md5 模块了。最简单的实现代码如下:



     1 !/usr/bin/env python
    
    2 coding : utf-8
    3
    4 import sys
    5 import hashlib
    6
    7 def md5sum(filename):
    8 file_object = open(filename, rb
    9 file_content = file_object.read()
    10 file_object.close()
    11 file_md5 = hashlib.md5(file_content)
    12 return file_md5
    13
    14 if __name__ == __main__:
    15 file_md5 = md5sum(sys.argv[1])
    16 print file_md5.hexdigest()


        竹风感觉有两个处所值得重视:
        一个是传入 hashlib.md5() 的应当是 file_object.read() ,如许才是对文件内容产生md5校验码,竹风刚开端就是没有应用 read() 办法,而是传入filename(如许的md5是对文件名生成的),导致产生的校验码不合错误;
        别的一个处所是,调用了 hashlib.md5() 后返回的是一个对象,想要获得 linux 下 md5sum 同样的结果,还要调用一下 hexdigest() 办法。


        当然,上方的代码推敲得不敷周全。若是要对一个斗劲大的文件进行校验,将会把文件内容一次读入内存,造成机能上的缺点。小我斗劲推荐从http://ryan-liu.iteye.com/blog/1530029供给的代码,代码如下:



     1 !/usr/bin/env python
    
    2 coding : utf-8
    3 import hashlib
    4
    5 def md5hex(word):
    6 MD5加密算法,返回32位小写16进制符号
    7
    8 if isinstance(word, unicode):
    9 word = word.encode(utf-8
    10 elif not isinstance(word, str):
    11 word = str(word)
    12 m = hashlib.md5()
    13 m.(word)
    14 return m.hexdigest()
    15
    16 def md5sum(fname):
    17 策画文件的MD5值
    18
    19 def read_chunks(fh):
    20 fh.seek(0)
    21 chunk = fh.read(8096
    22 while chunk:
    23 yield chunk
    24 chunk = fh.read(8096
    25 else: 最后要将游标放回文件开首
    26 fh.seek(0)
    27 m = hashlib.md5()
    28 if isinstance(fname, basestring) 29 and os.path.exists(fname):
    30 with open(fname, rb) as fh:
    31 for chunk in read_chunks(fh):
    32 m.(chunk)
    33 上传的文件缓存 或 已打开的文件流
    34 elif fname.__class__.__name__ in [StringIOStringO] 35 or isinstance(fname, file):
    36 for chunk in read_chunks(fname):
    37 m.(chunk)
    38 else:
    39 return
    40 return m.hexdigest()


    这段代码就足够强大了,每次读入8k的内容,然后调用 () ,来更新md5。
    PS:至于为什么是8k?这个就涉及到了IO大小方面的内容了。供给一篇文章,有爱好的可以看看懂得下:http://blog.sina.com.cn/s/blog_6200c1440100vt4z.html


    我所有的自负皆来自我的自卑,所有的英雄气概都来自于我的软弱。嘴里振振有词是因为心里满是怀疑,深情是因为痛恨自己无情。这世界没有一件事情是虚空而生的,站在光里,背后就会有阴影,这深夜里一片寂静,是因为你还没有听见声音。—— 马良《坦白书》
    分享到: