????????Base64是一種基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的表示方法。它已經(jīng)成為網(wǎng)絡(luò)上常見的傳輸8Bit字節(jié)代碼的編碼方式之一。
????????我們都知道ASCII字符集由95個(gè)可打印字符(0x20-0x7E)和33個(gè)控制字符(0x00-0x1F,0x7F)組成??纱蛴∽址娠@示在輸出設(shè)備上,例如熒屏或者打印紙上而控制字符沒法打印出來,但是每個(gè)字符,都對應(yīng)著一個(gè)特殊的控制功能的字符,因此這些字符簡稱功能字符或功能碼?Function Code?。如用記事本打開exe、jpg、pdf這些文件時(shí),我們都會看到一大堆亂碼,因?yàn)槎M(jìn)制文件包含很多無法顯示和打印的字符,所以如果要讓記事本這樣的文本處理軟件能處理二進(jìn)制數(shù)據(jù),就需要一個(gè)二進(jìn)制到字符串的轉(zhuǎn)換方法。
Base64編碼原理
????????Base64協(xié)議選用了”A-Z、a-z、0-9、+、/” 64個(gè)可打印字符構(gòu)成了Base64的索引表,如下

? ??????數(shù)值代表字符的索引,這個(gè)是標(biāo)準(zhǔn)Base64協(xié)議規(guī)定的,不能更改。
????Base64的碼表只有64個(gè)字符,如果要表達(dá)64個(gè)字符的話,使用6的bit即可完全表示(2的6次方為64)。
????因?yàn)锽ase64的編碼只有6個(gè)bit即可表示,而正常的字符是使用8個(gè)bit表示, 8和6的最小公倍數(shù)是24,所以4個(gè)Base64字符可以表示3個(gè)標(biāo)準(zhǔn)的ascll字符。如果是字符串轉(zhuǎn)換為Base64碼,會先把對應(yīng)的字符串轉(zhuǎn)換為ascll碼表對應(yīng)的數(shù)字,然后再把數(shù)字轉(zhuǎn)換為二進(jìn)制,取8位二進(jìn)制的前6位,剩下的2個(gè)二進(jìn)制位和后面的二進(jìn)制繼續(xù)拼接,依次類推,最后再把6個(gè)二進(jìn)制碼轉(zhuǎn)換為Base64對應(yīng)的編碼,如
字符串????? a??????b??????? c
ASCII?????97????? 98?????? 99
8bit?? 01100001 01100010 01100011
6bit?? 011000?? 010110?? 001001?? 100011
十進(jìn)制????? 24????? 22??????? 9??????? 35
對應(yīng)編碼??? Y???????W??????? J??????? j
????????3個(gè)ASCII字符剛好轉(zhuǎn)換成對應(yīng)的4個(gè)Base64字符。但是,當(dāng)需要轉(zhuǎn)換的字符數(shù)不是3的倍數(shù)的情況下該怎么辦呢?Base64規(guī)定,當(dāng)需要轉(zhuǎn)換的字符不是3的倍數(shù)時(shí),一律采用補(bǔ)0的方式湊足3的倍數(shù),如:

????????對于文本A,每6個(gè)Bit為一組,第一組轉(zhuǎn)換后為字符“Q”,第二組末尾補(bǔ)4個(gè)0轉(zhuǎn)換后為字符“Q”。剩下的使用“=”替代。即字符“A”通過Base64編碼后為“QQ==”。這就是Base64的編碼過程。
在python2中運(yùn)行如下命令查看
>>> import base64
>>> a=base64.b64encode('A')?
>>> a
'QQ=='
>>>?
?????? b64encode函數(shù)的參數(shù)為byte類型,如果字符為unicode編碼,需要先進(jìn)行轉(zhuǎn)碼,如
>>> a=base64.b64encode(u'中文'.encode('utf-8'))
>>> a
'5Lit5paH'
>>>?
?????? 解碼命令為
>>> base64.b64decode(a)
'\xe4\xb8\xad\xe6\x96\x87'???????? ??????????#“中文”的utf-8編碼格式
>>>?
>>> print base64.b64decode(a)
中文
Base64編碼的應(yīng)用
?????? Base64編碼的應(yīng)用場景有
1、實(shí)現(xiàn)簡單的數(shù)據(jù)加密,使用戶一眼望去完全看不出真實(shí)數(shù)據(jù)內(nèi)容,base64算法的復(fù)雜程度要小,效率要高相對較高。
很多下載類網(wǎng)站都提供“下載”的鏈接,其地址通常是加密的專用下載地址,如

其中旋風(fēng)地址就是由原始地址在其前后分別添加AA和ZZ,再經(jīng)過base64編碼后得到的。如
>>> a=base64.b64encode('www.baidu.com/img/sslm1_logo.gif')???
>>> a
'd3d3LmJhaWR1LmNvbS9pbWcvc3NsbTFfbG9nby5naWY='
>>>?
2、編碼的主要的作用不在于安全性,而在于讓內(nèi)容能在各個(gè)網(wǎng)關(guān)間無錯(cuò)的傳輸,這才是Base64編碼的核心作用。在計(jì)算機(jī)中任何數(shù)據(jù)都是按ascii碼存儲的,而ascii碼的128~255之間的值是不可見字符。而在網(wǎng)絡(luò)上交換數(shù)據(jù)時(shí),比如說從A地傳到B地,往往要經(jīng)過多個(gè)路由設(shè)備,由于不同的設(shè)備對字符的處理方式有一些不同,這樣那些不可見字符就有可能被處理錯(cuò)誤,這是不利于傳輸?shù)?。所以就先把?shù)據(jù)先做一個(gè)Base64編碼,統(tǒng)統(tǒng)變成可見字符,這樣出錯(cuò)的可能性就大降低了。
3、應(yīng)用在url中,url中&a=b是會作為參數(shù)名(a)和參數(shù)值(b)發(fā)送的,如果你發(fā)送的參數(shù)b中有&,那就會被瀏覽器認(rèn)為是另一個(gè)參數(shù)名了,而這不是你的本意。所以,這時(shí)候你就可以把參數(shù)值b通過Base64進(jìn)行編碼,而你的服務(wù)器在獲取到b后再解碼b,就得到了原本帶有&的b值了。
FYI,delete immediately if any infringements declared.