Python3學習筆記21 Base64

2021-09-18 01:15:28 字數 3254 閱讀 7682

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.括號中的內容也可以是變數名和計算公...