base64是一種用64個字元來表示任意二進位制資料的方法。
用記事本開啟exe、jpg、pdf這些檔案時,我們都會看到一大堆亂碼,因為二進位制檔案包含很多無法顯示和列印的字元,所以,如果要讓記事本這樣的文字處理軟體能處理二進位制資料,就需要乙個二進位製到字串的轉換方法。base64是一種常見的二進位制編碼方法。
base64的原理很簡單,首先,準備乙個包含64個字元的陣列:
[『a』,『b』,『c』,…『a』,『b』,『c』,…『0』,『1』,…』+』,』/』]
然後,對二進位制資料進行處理,每3個位元組一組,一共是3*8=24bit,劃為4組,每組正好6個bit:
這樣我們得到4個數字作為索引,然後查表,獲得相應的4個字元,就是編碼後的字串。
所以,base64編碼會把3位元組的二進位制資料編碼為4位元組的文字資料,長度增加33%,好處是編碼後的文字資料可以在郵件正文、網頁等直接展示。
如果要編碼的二進位制資料不是3的倍數,最後會剩下1個或2個位元組怎麼辦?base64用\x00位元組在末尾補足後,再在編碼的末尾加上1個或2個=號,表示補了多少位元組,解碼的時候,會自動去掉。
python內建的base64可以直接進行base64的編譯碼:
import base64
a=base64.b64encode(b'binaary\x00string')
print(a)
b=base64.b64decode(b'ymluywfyeqbzdhjpbmc=')
print(b)
輸出結果為:
b』ymluywfyeqbzdhjpbmc=』
b』binaary\x00string』
由於標準的base64編碼後可能出現字元+和/,在url中就不能直接作為引數,所以又有一種「url safe"的base64編碼,其實就是把字元+和/分別變成-和_:
c=base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
print(c)
d=base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
print(d)
e=base64.urlsafe_b64decode('abcd--__')
print(e)
輸出結果:
b』abcd++//』
b』abcd–__』
b』i\xb7\x1d\xfb\xef\xff』
還可以自己定義64個字元的排列順序,這樣就可以自定義base64編碼,不過,通常情況下完全沒有必要。
base64是一種通過查表的編碼方法,不能用於加密,即使使用自定義的編碼表也不行。
base64適用於小段內容的編碼,比如數字證書簽名、cookie的內容等。
由於=字元也可能出現在base64編碼中,當=用在url、cookie裡面會造成歧義,所以,很多base64編碼後會把=去掉:
去掉=後怎麼解碼呢?因為base64是把3個位元組變為4個位元組,所以,base64編碼的長度永遠是4的倍數,因此需要加上=把base64字串的長度變為4的倍數,就可以正常解碼了。
小結:base64是一種任意二進位製到文字字串的編碼方法,常用於在url、cookie、網頁中傳輸少量二進位制資料。
請寫乙個能處理去掉=的base64解碼函式:
import base64
def safe_base64_decode(s):
#新增等於號
if len(s)%4!=0:
s=s+bytes('=',encoding='utf-8')*(4-len(s)%4)
print("1:%s"%s)
#解決字串和bytes型別
if not isinstance(s,bytes):
s=byte(s,encoding='utf-8')
print('s:%s'%s)
#解碼base64_string=base64.b64decode(s)
print("base64:%s"%base64_string)
return base64_string
#測試assert b'abcd'==safe_base64_decode(b'ywjjza=='),safe_base64_decode('ywjjza==')
assert b'abcd'==safe_base64_decode(b'ywjjza'),safe_base64_decode('ywjjza')
print('ok')
輸出結果:
base64:b』abcd』
1:b』ywjjza==』
base64:b』abcd』
ok準確地講,python沒有專門處理位元組的資料型別。但由於str即是字串,又可以表示位元組,所以位元組陣列=str。而在c語言中,我們可以很方便地用struct、union來處理位元組和int,float的轉換。
在python中,比方說要把乙個32位無符號整數變成位元組,也就是4個長度的bytes,你得配合位運算子這麼寫:
非常麻煩。如果換成浮點數就無能為力了。
好在python提供了乙個struct模組來解決bytes和其他二進位制資料型別的轉換。
struct的pack函式把任意資料型別變成bytes:
unpack把bytes變成相應的資料型別:
所以,儘管python不適合編寫底層操作位元組流的**,但在對效能要求不高的地方,利用struct就方便多了。
windows的位**件(.bmp)是一種非常簡單的檔案格式,我們來用struct分析一下。
首先找乙個bmp檔案,沒有的話用」畫圖「畫乙個。
讀入前30個位元組來分析:
Python3學習筆記
最近在起步學python,聚合一下這個過程中蒐集的資源和對一些基本知識做個小總結,語法基於python3,方便以後查詢。python官方文件 不錯的基礎課程 基本語法 演算法 建模 練習 以下是整理常用可能遺忘的基礎點 python3中的輸入是input 獲得使用者輸入的字串 a input ple...
python3學習筆記
redis訊息佇列的使用 coding utf 8 created on tue mar 26 15 58 34 2019 author admin import redis class redisqueue object def init self,name,namespace queue red...
python3 學習筆記
python3學習筆記 python基礎 輸出 print 括號中加上想要輸出的資料,就可以將指定內容輸出至螢幕。1.輸出的時候要注意資料型別。字串,整數等等 2.括號中可以包含多個字串,使用逗號隔開就可以了。但是每次輸出遇到這個連線逗號的時候都會輸出乙個空格。3.括號中的內容也可以是變數名和計算公...