Python的學習(三十) ---- Python實現文件md5校驗

Linux下校驗文件MD5值,最簡單的方法就是執行md5sum命令
md5sum filename
原本打算用subprocess調用系統命令來獲取md5值,

import subprocess,shlex
cmd = "md5sum filename"
p = subprocess(shlex.split(cmd), stdout=subprocess.PIPE)
print p.stdout.read()

不過python有自帶的MD5模塊hashlib,用起來簡單很多,
Python Hashlib模塊的使用說明 http://docs.python.org/2/library/hashlib.html
fd = hashlib.md5() #獲取一個MD5加密算法對象
fd.update("string") #指定需要加密的字符串
fd.hexdigest() #獲取加密後的16進制字符串

實例

 #!/usr/bin/env python           
 #coding : utf-8 3  4 import sys 
 import hashlib                  
                                 
 def md5sum(filename):           
     fd = open(filename,"r")
     fcont = fd.r
     fd.close()         
     fmd5 = hashlib.md5(fcont)
     return fmd5             
                                 
 if __name__ == "__main__":      
     fmd5 = md5sum(sys.argv[1])
     print fmd5.hexdigest()  

其中fmd5 = hashlib.md5(fcont)等同於
fmd5 = hashlib.md5(fcont)
fmd5.update(fcont)

需要注意的是,傳入 hashlib.md5() 的應該是 文件內容而不是文件名 ,這樣纔是對文件內容產生md5校驗碼;
另外,調用了 hashlib.md5() 後返回的是一個對象,想要獲得linux下 md5sum 同樣的效果,還要調用一下 hexdigest() 方法。

但是,這個方法有點過於粗暴,當檢驗大文件時,一次將所有文件內容讀入內存,實在耗費較大,
網上給出實例http://blog.csdn.net/shanliangliuxing/article/details/10115397
根據文件塊長度,依次獲取文件內容讀入內存,通過update()逐次更新校驗值,

#!/usr/bin/env python 2

 #coding : utf-8 3 import hashlib
  
  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 ""40     return m.hexdigest()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章