1. 程式人生 > >Python的學習(三十) ---- Python實現檔案md5校驗

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() 方法。

#!/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()