Python基礎知識(26):常用內建模塊(Ⅱ) 1、hashlib Python的hashlib提供了常見的摘要演算法,如MD5,SHA1等 摘要演算法又稱哈希演算法、散列演算法。 (1)它通過一個函數,把任意長度的數據轉換為一個長度固定的數據串(通常用16進位的字元串表示) (2)摘要演算法就是通過摘要函 ...
Python基礎知識(26):常用內建模塊(Ⅱ)
1、hashlib
Python的hashlib提供了常見的摘要演算法,如MD5,SHA1等
摘要演算法又稱哈希演算法、散列演算法。
(1)它通過一個函數,把任意長度的數據轉換為一個長度固定的數據串(通常用16進位的字元串表示)
(2)摘要演算法就是通過摘要函數f()
對任意長度的數據data
計算出固定長度的摘要digest
,目的是為了發現原始數據是否被人篡改過
MD5
MD5是最常見的摘要演算法,速度很快,生成結果是固定的128 bit位元組,通常用一個32位的16進位字元串表示
import hashlib md5 = hashlib.md5() md5.update('How to use md5 in python hashlib'.encode('utf-8')) print(md5.hexdigest()) 結果: 8b6e4d30c576051f3ca4be97e8314d15
SHA1
import hashlib sha1 = hashlib.sha1() sha1.update('How to use SHA1 in python hashlib'.encode('utf-8')) print(sha1.hexdigest()) 結果: 8a4dbc942c7ff059115b56645ab484c4188bd5ce
SHA1的結果是160 bit位元組,通常用一個40位的16進位字元串表示
比SHA1更安全的演算法是SHA256和SHA512,不過越安全的演算法不僅越慢,而且摘要長度更長
摘要演算法的應用
用戶登錄網站的用戶名和口令都存儲資料庫,口令使用摘要演算法進行加密
當用戶登錄時,首先計算用戶輸入的明文口令的MD5,然後和資料庫存儲的MD5對比,如果一致,說明口令輸入正確,如果不一致,口令肯定錯誤
要確保存儲的用戶口令不是那些已經被計算出來的常用口令的MD5,這一方法通過對原始口令加一個複雜字元串來實現,俗稱“加鹽
經過Salt處理的MD5口令,只要Salt不被黑客知道,即使用戶輸入簡單口令,也很難通過MD5反推明文口令
設計一個驗證用戶登錄的函數,根據用戶輸入的口令是否正確
import hashlib db = { 'michael': 'e10adc3949ba59abbe56e057f20f883e', 'bob': '878ef96e86145580c38c87f0410ad153', 'alice': '99b1c2188db85afee403b1536010c2c9' } def calc_md5(password): md5 = hashlib.md5() md5.update(password.encode('utf-8')) return md5.hexdigest() def login(user, password): md5 = calc_md5(password) if user in db and md5 in db.get(user): print('Welcome') else: print('Incorrect username or password') login('michael', '123456') login('bob', 'abc999') login('alice', 'alice2008') login('michael', '1234567') login('bob', '123456') login('alice', 'Alice2008') 結果: Welcome Welcome Welcome Incorrect username or password Incorrect username or password Incorrect username or password
HMAC是密鑰相關的哈希運算消息認證碼,HMAC運算利用哈希演算法,以一個密鑰和一個消息為輸入,生成一個消息摘要作為輸出
Python自帶的hmac模塊實現了標準的Hmac演算法,它利用一個key對message計算“雜湊”後的hash,使用hmac演算法比標準hash演算法更安全,因為針對相同的message,不同的key會產生不同的hash
import hmac message = b'Hello,world!' key = b'secret' h = hmac.new(key, message, digestmod='MD5') print(h.hexdigest()) 結果: 21db988f124ebc9fade5492afb9df52d
3、itertools
Python的內建模塊itertools
提供了非常有用的用於操作迭代對象的函數
(1)count
count()
會創建一個無限的迭代器,所以上述代碼會列印出自然數序列,根本停不下來,只能按Ctrl+C
退出
import itertools natuals = itertools.count(1) for i in natuals: print(i)
(2)cycle
cycle()
會把傳入的一個序列無限重覆下去
import itertools cs = itertools.cycle('ABC') for i in cs: print(i)
(3)repeat
repeat()
負責把一個元素無限重覆下去,不過如果提供第二個參數就可以限定重覆次數
import itertools ns = itertools.repeat('A', 3) for i in ns: print(i) 結果: A A A
(4)takewhile
無限序列只有在for
迭代時才會無限地迭代下去,如果只是創建了一個迭代對象,它不會事先把無限個元素生成出來,事實上也不可能在記憶體中創建無限多個元素
無限序列雖然可以無限迭代下去,但是通常我們會通過takewhile()
等函數根據條件判斷來截取出一個有限的序列
import itertools natuals = itertools.count(1) ns = itertools.takewhile(lambda x:x<=10, natuals) for i in ns: print(i) 結果: 1 ... 10
(5)chain
chain()
可以把一組迭代對象串聯起來,形成一個更大的迭代器
import itertools for c in itertools.chain('ABC','123'): print(c) 結果: A B C 1 2 3
(6)groupby
groupby()
把迭代器中相鄰的重覆元素挑出來放在一起
實際上挑選規則是通過函數完成的,只要作用於函數的兩個元素返回的值相等,這兩個元素就被認為是在一組的,而函數返回值作為組的key
如果我們要忽略大小寫分組,就可以讓元素'A'
和'a'
都返回相同的key
import itertools for key,group in itertools.groupby('monent'): print(key,list(group)) for key,group in itertools.groupby('AAaaaBBBbbccC', lambda c:c.upper()): print(key,list(group)) 結果: m ['m'] o ['o'] n ['n'] e ['e'] n ['n'] t ['t'] A ['A', 'A', 'a', 'a', 'a'] B ['B', 'B', 'B', 'b', 'b'] C ['c', 'c', 'C']
4、contextlib
在Python中,讀寫文件這樣的資源要特別註意,必須在使用完畢後正確關閉它們。正確關閉文件資源的一個方法是使用try...finally
寫try...finally
非常繁瑣,使用Python的with
語句更加方便
#try..finally... try: f = open('/path/to/file', 'r') f.read() finally: if f: f.close() #with with open('/path/to/file', 'r') as f: f.read()
實現上下文管理是通過__enter__
和__exit__
這兩個方法實現的,任何對象只要正確實現了上下文管理,就可以用於with
語句
@contextmanager
編寫__enter__
和__exit__
仍然很繁瑣,因此Python的標準庫contextlib
提供了更簡單的寫法
@closing
如果一個對象沒有實現上下文,我們就不能把它用於with
語句。這個時候,可以用closing()
來把該對象變為上下文對象