Base64编码原理分析
Base64是網(wǎng)絡(luò)上最常見(jiàn)的用于傳輸8Bit字節(jié)代碼的編碼方式之一,在了解Base64編碼之前,先了解幾個(gè)基本概念:位、字節(jié)。
位:"位(bit)"是計(jì)算機(jī)中最小的數(shù)據(jù)單位。每一位的狀態(tài)只能是0或1;
字節(jié):8個(gè)二進(jìn)制位構(gòu)成1個(gè)"字節(jié)(Byte)",字節(jié)是存儲(chǔ)空間的基本計(jì)量單位。1個(gè)字節(jié)可以儲(chǔ)存1個(gè)英文字母,2個(gè)字節(jié)可以存儲(chǔ)1個(gè)漢字;
Base64編碼的作用
因?yàn)橛行┚W(wǎng)絡(luò)傳送渠道并不支持所有的字節(jié),例如傳統(tǒng)的郵件只支持可見(jiàn)字符的傳送,像ASCII碼的控制字符就不能通過(guò)郵件傳送。這樣就受到了很大的限制,比如圖片二進(jìn)制流的每個(gè)字節(jié)不可能全部是可見(jiàn)字符,所以就傳送不了。最好的方法就是在不改變傳統(tǒng)協(xié)議的情況下,開(kāi)辟一種新的方案來(lái)支持二進(jìn)制文件的傳送。把不可見(jiàn)字符用可見(jiàn)字符來(lái)表示。而B(niǎo)ase64就是一種基于64個(gè)可見(jiàn)字符來(lái)表示二進(jìn)制數(shù)據(jù)的表示方法。
擴(kuò)展:不可見(jiàn)字符其實(shí)并不是不顯示,只是這些字符在屏幕上顯示不出來(lái),比如:換行符、回車、退格......字符。
Base64編碼的原理
Base64可以將ASCII字符串或者是二進(jìn)制編碼成只包含A—Z,a—z,0—9,+,/ 這64個(gè)字符( 26個(gè)大寫字母,26個(gè)小寫字母,10個(gè)數(shù)字,1個(gè)+,一個(gè) / 剛好64個(gè)字符)。這64個(gè)字符用6個(gè)bit位就可以全部表示出來(lái),一個(gè)字節(jié)有8個(gè)bit 位,那么還剩下兩個(gè)bit位,這兩個(gè)bit位用0來(lái)補(bǔ)充。其實(shí),一個(gè)Base64字符仍然是8個(gè)bit位,但是有效部分只有右邊的6個(gè) bit,左邊兩個(gè)永遠(yuǎn)是0。
Base64的編碼規(guī)則是將3個(gè)8位字節(jié)(3×8=24位)編碼成4個(gè)6位的字節(jié)(4×6=24位),之后在每個(gè)6位字節(jié)前面,補(bǔ)充兩個(gè)0,形成4個(gè)8位字節(jié)的形式,那么取值范圍就變成了0~63。又因?yàn)?的6次方等于64,所以每6個(gè)位組成一個(gè)單元。
擴(kuò)展:1、為什么取值范圍是0~63?
可以回顧一下二進(jìn)制轉(zhuǎn)換10進(jìn)制的方法:
最小的二進(jìn)制:00000000轉(zhuǎn)換為10進(jìn)制的結(jié)果是0;
最大的二進(jìn)制:00111111轉(zhuǎn)換為10進(jìn)制的結(jié)果是:
0×27+0×26+1×25+1×24+1×23+1×22+1×21+1×20 = 63
Base64將3個(gè)字節(jié)轉(zhuǎn)變?yōu)?個(gè)字節(jié),因此,編碼后的代碼量(以字節(jié)為單位)約比編碼前的代碼量多了1/3。如果代碼量正好是3的整數(shù)倍,那么恰好多了1/3。但如果不是,那么,當(dāng)多出的代碼量不是3的整數(shù)倍時(shí),代碼量除以3的余數(shù)就是2或者1。轉(zhuǎn)換的時(shí)候,結(jié)果不夠6位的用0來(lái)補(bǔ)上相應(yīng)的位置,之后再在6位的前面補(bǔ)兩個(gè)0。轉(zhuǎn)換完空出的結(jié)果就用就用“=”來(lái)補(bǔ)位,總之要保證最后編碼出來(lái)得字節(jié)數(shù)是4的倍數(shù)。
2、為什么要保證最后編碼出來(lái)的字節(jié)數(shù)是4的倍數(shù)?
因?yàn)锽ase64編碼時(shí),是將3個(gè)字節(jié)轉(zhuǎn)變?yōu)?個(gè)字節(jié),最終得到的字節(jié)數(shù)必然是4的倍數(shù)
Base64編碼的一個(gè)主要目的,是把任何字符都用“可視”字符表現(xiàn)出來(lái)。先把字符串拆開(kāi),成為六位二進(jìn)制(前兩位補(bǔ)零)的形式,這樣每個(gè)字符的范圍都在0-63之間了。再用BASE64的編碼表,把取值范圍在0-63的字符變成“可視”字符。如果不加零或只加一個(gè)零,那么取值范圍就會(huì)是0-255或0-127,BASE64的編碼表就要重新規(guī)定了。
擴(kuò)展:為什么取值范圍限制在0~63而不是0~255或者0~127?
估計(jì)可見(jiàn)字符有限,沒(méi)有那么多的可見(jiàn)字符或者是Base64編碼的規(guī)則、約定
下圖是Base64編碼對(duì)照表,數(shù)值代表字符的索引,這個(gè)是標(biāo)準(zhǔn)Base64協(xié)議規(guī)定的,不能更改。
舉例:
例1:
字符:SLF
對(duì)應(yīng)ASCII碼:S:83 L:76 F:70
轉(zhuǎn)換成對(duì)應(yīng)的二進(jìn)制:
83:01010011、76:01001100、70:01000110
為了解釋更加清晰,以下圖示例:
例2:
字符:M
對(duì)應(yīng)ASCII碼:M:77
轉(zhuǎn)換成對(duì)應(yīng)的二進(jìn)制:
77:01001101
轉(zhuǎn)換結(jié)果:
總結(jié):Base64編碼并不是真正的加密方式,它只是從二進(jìn)制到字符的轉(zhuǎn)換過(guò)程,說(shuō)Base64編碼是加密方法,只是因?yàn)榻?jīng)過(guò)Base64編碼之后,讓人一眼看上去不知道什么內(nèi)容而已。