struct
Python提供了一個(gè)struct
模塊來(lái)解決bytes
和其他二進(jìn)制數(shù)據(jù)類型的轉(zhuǎn)換。
struct
的pack
函數(shù)把任意數(shù)據(jù)類型變成bytes
:
>>> bs = bytes([b1,b2,b3,b4])
>>> bs
b'\x00\x9c@c'
pack
的第一個(gè)參數(shù)是處理指令,'>I'
的意思是:
>
表示字節(jié)順序是big-endian,也就是網(wǎng)絡(luò)序,I
表示4字節(jié)無(wú)符號(hào)整數(shù)挂洛。
后面的參數(shù)個(gè)數(shù)要和處理指令一致。
unpack
把bytes
變成相應(yīng)的數(shù)據(jù)類型:
>>> struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')
(4042322160, 32896)
根據(jù)>IH
的說(shuō)明,后面的bytes依次變?yōu)?code>I:4字節(jié)無(wú)符號(hào)整數(shù)和H
:2字節(jié)無(wú)符號(hào)整數(shù)纵东。
所以,盡管Python不適合編寫(xiě)底層操作字節(jié)流的代碼啥寇,但在對(duì)性能要求不高的地方偎球,利用struct
就方便多了洒扎。
struct
模塊定義的數(shù)據(jù)類型可以參考Python官方文檔:
https://docs.python.org/3/library/struct.html#format-characters
hashlib
Python的hashlib提供了常見(jiàn)的摘要算法,如MD5衰絮,SHA1等等袍冷。
什么是摘要算法呢?摘要算法又稱哈希算法猫牡、散列算法胡诗。它通過(guò)一個(gè)函數(shù),把任意長(zhǎng)度的數(shù)據(jù)轉(zhuǎn)換為一個(gè)長(zhǎng)度固定的數(shù)據(jù)串(通常用16進(jìn)制的字符串表示)淌友。
摘要算法就是通過(guò)摘要函數(shù)f()
對(duì)任意長(zhǎng)度的數(shù)據(jù)data
計(jì)算出固定長(zhǎng)度的摘要digest
煌恢,目的是為了發(fā)現(xiàn)原始數(shù)據(jù)是否被人篡改過(guò)。
摘要算法之所以能指出數(shù)據(jù)是否被篡改過(guò)震庭,就是因?yàn)檎瘮?shù)是一個(gè)單向函數(shù)瑰抵,計(jì)算f(data)
很容易,但通過(guò)digest
反推data
卻非常困難器联。而且二汛,對(duì)原始數(shù)據(jù)做一個(gè)bit的修改,都會(huì)導(dǎo)致計(jì)算出的摘要完全不同拨拓。
以常見(jiàn)的摘要算法MD5為例肴颊,計(jì)算出一個(gè)字符串的MD5值:
>>> import hashlib
>>> md5 = hashlib.md5()
>>> md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
>>> print(md5.hexdigest())
d26a53750bc40b38b65a520292f69306
如果數(shù)據(jù)量很大,可以分塊多次調(diào)用update()
渣磷,最后計(jì)算的結(jié)果是一樣的:
import hashlib
md5 = hashlib.md5()
md5.update('how to use md5 in '.encode('utf-8'))
md5.update('python hashlib?'.encode('utf-8'))
print(md5.hexdigest())
MD5是最常見(jiàn)的摘要算法婿着,速度很快,生成結(jié)果是固定的128 bit字節(jié)幸海,通常用一個(gè)32位的16進(jìn)制字符串表示祟身。
另一種常見(jiàn)的摘要算法是SHA1,調(diào)用SHA1和調(diào)用MD5完全類似:
>>> import hashlib
>>> sha1 = hashlib.sha1()
>>> sha1.update('how to use sha1 in python hashlib?'.encode('utf-8'))
>>> print(sha1.hexdigest())
2c76b57293ce30acef38d98f6046927161b46a44
SHA1的結(jié)果是160 bit字節(jié)物独,通常用一個(gè)40位的16進(jìn)制字符串表示袜硫。
比SHA1更安全的算法是SHA256和SHA512,不過(guò)越安全的算法不僅越慢挡篓,而且摘要長(zhǎng)度更長(zhǎng)婉陷。
摘要算法應(yīng)用
hmac
Python自帶的hmac模塊實(shí)現(xiàn)了標(biāo)準(zhǔn)的Hmac算法。我們來(lái)看看如何使用hmac實(shí)現(xiàn)帶key的哈希官研。
我們首先需要準(zhǔn)備待計(jì)算的原始消息message秽澳,隨機(jī)key,哈希算法戏羽,這里采用MD5担神,使用hmac的代碼如下:
>>> import hmac
>>> message = b'Hello, world!'
>>> key = b'secret'
>>> h = hmac.new(key, message, digestmod='MD5')
>>> # 如果消息很長(zhǎng),可以多次調(diào)用h.update(msg)
>>> h.hexdigest()
'fa4ee7d173f2d97ee79022d1a7355bcf'
可見(jiàn)使用hmac和普通hash算法非常類似始花。hmac輸出的長(zhǎng)度和原始哈希算法的長(zhǎng)度一致妄讯。需要注意傳入的key和message都是bytes
類型孩锡,str
類型需要首先編碼為bytes
。