Python MD5校验文件
今天看到了一个用Python校验文件md5的代码,但是本人Python不是很熟,所以里面有很多语法看的不是很懂,大概讲讲吧.
首先要想校验一个文件的md5值在Linux下很方便,命令行就可以校验:
1 | ➜ ~ md5sum 订单数据.xls |
虽然你也可以调用Python来校验文件的md5,但是这样很不方便,也不能保证windows下也可以运行吧,Python中也md5校验的函数,Python 2.5之后推荐使用hashlib
来代替md5
模块来做校验.
简单的MD5校验
1 | #!/usr/bin/env python |
注意:hashlib.md5()
返回的是一个对象,要想得到md5值,还需要调用一下hexdigest()
方法.还有一个地方需要注意一下,这个校验方法有个很大的缺陷,由于是要校验文件里面的内容,所以每次是把文件读到内存的,试想一下,如果这个文件很大,先不说慢,更有可能程序就直接卡死了.
改进的MD5校验
下面的代码确实写的很牛逼,对于我这种刚学Python的渣渣来说,很多地方都看的不太明白,先把程序贴出来,后面有一些程序中不懂的地方的一些详尽的解释.优化之后的代码:
加密字符串
1 | def md5hex(word): |
**解释:**查了一下Python里关于str
和unicode
的区别,简单来说就是str
类似于byte[]
,即字节字符串.而unicode
类似于char[]
.说白了就是Python内部存储用unicode
,而在和人交互的时候用str
,str是字节串,由unicode经过编码(encode)后的字节组成的,所以它们的关系就是unicode.encode()-->str
或者str.decode()-->unicode()
.时刻记住:
unicode才是真正的字符串.
加密文件
1 | def md5sum(file_name): |
这段程序写的确实很牛逼,我稍微解释一下:
8~15
行:的意思就是每次返回读取的文件的8k的内容,下次从上次读取的地方继续读取,如果读完了,就把游标重新放到文件开头.注意这里面用到了yield
,对这个关键字不熟的可以简单把他理解为关键字return
.但是它和return
不同的地方在于,再次调用函数的时候,上次调用的变量还是有效的,也就是说它不是从文件的开头重新读,而是接着上回读的地方再读8k的内容18
行:isinstance(file_name, basestring)
这个是判断文件名是不是一个basestring
类型,basestring
是str
和unicode
的父类,这个类是个抽象类,不能被实例化,不过可以被用来判断一个对象是不是字符串.with
关键字,简单理解为try/catch
就可以了,即使发生了异常,文件也可以正常关闭.23
行:StringIO
和cStringIO
与file
对象非常像,指内存里的文件,例如上传的文件缓存或者已经打开的文件流,那么就不用打开文件,直接读就行
总结
这个程序其实就是每次读取8k的内容,然后更新已经读取的内容的md5
值,核心代码:
1 | for chunk in read_chunks(fp): |
如果不明白update()
的用法,可以测试一下:
1 | >>> import hashlib |
所以可以看到,update()
方法其实并不会丢弃上一次校验的结果,就是在不停的累加,尤其适合处理大文件.