MD5校驗

很久沒有寫隨筆了,正好這兩天能夠休整一下,藉此機會總結下最近使用python的小體會。html

    我的體會文件校驗在下載文件時使用較多,在linux下最簡單的實現方式就是:python

1 $ md5sum filename
2 21c7ee192e64569ce43cfb869bdb2755  filename

     固然在python當中也有對應的模塊能夠實現此功能,在python2.5以前能夠使用 md5 模塊,可是在python2.5之後就推薦使用 hashlib 來代替 md5 模塊了。最簡單的實現代碼以下:linux

#!/usr/bin/env python
#coding : utf-8

import sys
import hashlib

def md5sum(filename):
    file_object = open(filename, 'rb')
    file_content = file_object.read()
    file_object.close()
    file_md5 = hashlib.md5(file_content)
    return file_md5

if __name__ == "__main__":
    file_md5 = md5sum(sys.argv[1])
    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提供的代碼,代碼以下:緩存

#!/usr/bin/env python
#coding : utf-8
import hashlib, os

def md5hex(word):
    """ MD5加密算法,返回32位小寫16進制符號
    """
    if isinstance(word, unicode):
        word = word.encode("utf-8")
    elif not isinstance(word, str):
        word = str(word)
    m = hashlib.md5()
    m.update(word)
    return m.hexdigest()

def md5sum(fname):
    """ 計算文件的MD5值
    """
    def read_chunks(fh):
        fh.seek(0)
        chunk = fh.read(8096)
        while chunk:
            yield chunk
            chunk = fh.read(8096)
        else: #最後要將遊標放回文件開頭
            fh.seek(0)
    m = hashlib.md5()
    if isinstance(fname, basestring) \
            and os.path.exists(fname):
        with open(fname, "rb") as fh:
            for chunk in read_chunks(fh):
                m.update(chunk)
    #上傳的文件緩存 或 已打開的文件流
    elif fname.__class__.__name__ in ["StringIO", "StringO"] \
            or isinstance(fname, file):
        for chunk in read_chunks(fname):
            m.update(chunk)
    else:
        return ""
    return m.hexdigest()

還能夠用:性能

    # 大文件的MD5值
    def getFileMd5(self, filename):
        if not os.path.isfile(filename):
            return
        myhash = hashlib.md5()
        f = file(filename, 'rb')
        while True:
            b = f.read(8096)
            if not b:
                break
            myhash.update(b)
        f.close()
        return myhash.hexdigest()

 

PS:至於爲何是8k?這個就涉及到了IO大小方面的內容了。提供一篇文章,有興趣的能夠看看了解下:http://blog.sina.com.cn/s/blog_6200c1440100vt4z.html加密

 

轉載:http://www.cnblogs.com/PandaBamboo/archive/2013/05/10/3071233.htmlspa

相關文章
相關標籤/搜索