Base64是什么政钟?
個(gè)人理解:Base64
是一種編碼方式蜈敢,和ASCll
一樣雕凹,只是一種編碼方式而已殴俱,但是兩者用到的場(chǎng)景不同。
我看到百度百科上的Base64解釋上有這樣一段話:
采用Base64編碼具有不可讀性枚抵,需要解碼后才能閱讀
總覺(jué)得‘閱讀‘這個(gè)詞怪怪的线欲,在我碰到的業(yè)務(wù)場(chǎng)景中,列如圖片的Base64
化傳輸俄精、秘鑰密文的Base64
化保存等询筏,其原內(nèi)容都不是需要人閱讀的榕堰,真正的’閱讀‘者都是機(jī)器竖慧。
思考Base64產(chǎn)生的原因
思考一個(gè)場(chǎng)景:對(duì)一段文字進(jìn)行加密,并傳輸給服務(wù)端逆屡。
我們一般先會(huì)將這段文字轉(zhuǎn)成二進(jìn)制數(shù)據(jù)圾旨,然后通過(guò)調(diào)用系統(tǒng)的加密算法,然后得到一串新的二進(jìn)制數(shù)據(jù)魏蔗,那么如何把這段二進(jìn)制數(shù)據(jù)傳給服務(wù)端呢砍的?
平時(shí)我們和服務(wù)端傳輸?shù)臄?shù)據(jù)基本都是utf8
格式的,那么這段二進(jìn)制數(shù)據(jù)能直接轉(zhuǎn)成utf8
格式呢莺治?顯然是不可能的廓鞠,utf8
的每個(gè)字節(jié)前幾位的bit都是有特殊含義的(具體看utf8
的生成規(guī)則)帚稠,但是加密得到的二進(jìn)制數(shù)據(jù)肯定輸無(wú)序的,所以最好將密文的二進(jìn)制數(shù)據(jù)先轉(zhuǎn)成一種能被utf8
編碼的格式床佳,然后就能和服務(wù)端進(jìn)行utf8
格式的通信了
我們來(lái)看看平時(shí)常常提到的幾種編碼格式滋早。
先看看utf16
和utf32
,其實(shí)他們和utf8
一樣砌们,都是對(duì)Unicode
碼的一種編碼杆麸。我們從電腦屏幕上看到的每一個(gè)字,每一個(gè)符號(hào)浪感,甚至有些表情都對(duì)應(yīng)一個(gè)Unicode
碼昔头,那么可以用Unicode
碼編碼密文二進(jìn)制數(shù)據(jù)么?答案是不可以影兽。拿utf32
舉例揭斧,它其實(shí)就是用4個(gè)字節(jié)表示一個(gè)Unicode
碼,但4個(gè)字節(jié)有多少種組合呢峻堰?種未蝌,Unicode
碼的個(gè)數(shù)只是其中的一部分,但是Unicode
碼并不是固定的茧妒,它每年還在增加萧吠。如果密文數(shù)據(jù)正好落在Unicode碼沒(méi)有的地方,系統(tǒng)就展示不出來(lái)了桐筏。而且如果真有一段密文用utf16
展示纸型,里面出現(xiàn)了英文、中文梅忌、韓文狰腌、數(shù)學(xué)符號(hào)、表情等牧氮,你會(huì)不會(huì)瘋掉(手動(dòng)滑稽)
用ASCll
碼表示琼腔,似乎是一個(gè)很好的注意,因?yàn)?code>ASCll碼已經(jīng)排滿踱葛,能做到二進(jìn)制和符號(hào)一一對(duì)應(yīng)的關(guān)系丹莲。但為什么不可以呢,或者說(shuō)有什么不方便呢尸诽?一方面ASCll
碼中有許多特殊字符甥材,列如'
、"
性含、\
等等替废,在展示的時(shí)候巢价,有些地方需要加轉(zhuǎn)義符折欠,有些地方不需要添加,會(huì)比較混亂芝发。另一方面ASCll
碼排在前面的一些位置并不是符號(hào)能展示出來(lái),列如7號(hào)位的響鈴苛谷。
其實(shí)到這里離Base64
的產(chǎn)生已經(jīng)很接近了后德。如果我們把ASCll
碼中那些不能展示出來(lái)的位置,和一些特殊字符的位置去掉抄腔,形成一種新的編碼瓢湃,那就能很好的展示出密文內(nèi)容了『丈撸基礎(chǔ)的ASCll
碼占7個(gè)bit位绵患,如果去掉一些,那新的編碼格式就用6個(gè)bit位好了悟耘,落蝙。Base64
就應(yīng)運(yùn)而生了。
當(dāng)然暂幼,上面都是我個(gè)人的理解筏勒。Base64
算法主要最早用于解決電子郵件傳輸問(wèn)題。在早期旺嬉,由于歷史問(wèn)題管行,電子郵件只允許傳輸ASCII碼字符。當(dāng)傳輸非ASCII碼時(shí)邪媳,網(wǎng)關(guān)很可能將非ASCII碼的二進(jìn)制位調(diào)整捐顷,即將非ASCII碼的8位二進(jìn)制的最高位設(shè)為0。當(dāng)用戶收到郵件時(shí)雨效,可想而知迅涮,收到的就是 一份亂碼的郵件。
Base64的規(guī)則
所謂的Base64
徽龟,就是64個(gè)符號(hào)來(lái)表示6個(gè)bit位的二進(jìn)制流叮姑。這64個(gè)符號(hào)分別為a-z,A-Z据悔,0-9及+
和/
传透。這里有張對(duì)照表
索引 | 符號(hào) | 索引 | 符號(hào) | 索引 | 符號(hào) | 索引 | 符號(hào) |
---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w |
1 | B | 17 | R | 33 | h | 49 | x |
2 | C | 18 | S | 34 | i | 50 | y |
3 | D | 19 | T | 35 | j | 51 | z |
4 | E | 20 | U | 36 | k | 52 | 0 |
5 | F | 21 | V | 37 | l | 53 | 1 |
6 | G | 22 | W | 38 | m | 54 | 2 |
7 | H | 23 | X | 39 | n | 55 | 3 |
8 | I | 24 | Y | 40 | o | 56 | 4 |
9 | J | 25 | Z | 41 | p | 57 | 5 |
10 | K | 26 | a | 42 | q | 58 | 6 |
11 | L | 27 | b | 43 | r | 59 | 7 |
12 | M | 28 | c | 44 | s | 60 | 8 |
13 | N | 29 | d | 45 | t | 61 | 9 |
14 | O | 30 | e | 46 | u | 62 | + |
15 | P | 31 | f | 47 | v | 63 | / |
具體來(lái)說(shuō),轉(zhuǎn)換方式可以分為四步屠尊。
- 第一步旷祸,將每三個(gè)字節(jié)作為一組,一共是24個(gè)二進(jìn)制位讼昆。
- 第二步,將這24個(gè)二進(jìn)制位分為四組,每個(gè)組有6個(gè)二進(jìn)制位浸赫。
- 第三步闰围,在每組前面加兩個(gè)00,擴(kuò)展成32個(gè)二進(jìn)制位既峡,即四個(gè)字節(jié)羡榴。
- 第四步,根據(jù)下表运敢,得到擴(kuò)展后的每個(gè)字節(jié)的對(duì)應(yīng)符號(hào)校仑,這就是Base64的編碼值。
舉一個(gè)具體的實(shí)例传惠,演示英語(yǔ)單詞Man如何轉(zhuǎn)成Base64編碼迄沫。
- 第一步,"M"卦方、"a"羊瘩、"n"的ASCII值分別是77、97盼砍、110尘吗,對(duì)應(yīng)的二進(jìn)制值是01001101、01100001浇坐、01101110睬捶,將它們連成一個(gè)24位的二進(jìn)制字符串010011010110000101101110。
- 第二步近刘,將這個(gè)24位的二進(jìn)制字符串分成4組侧戴,每組6個(gè)二進(jìn)制位:010011、010110跌宛、000101酗宋、101110。
- 第三步疆拘,在每組前面加兩個(gè)00蜕猫,擴(kuò)展成32個(gè)二進(jìn)制位,即四個(gè)字節(jié):00010011哎迄、00010110回右、00000101、00101110漱挚。它們的十進(jìn)制值分別是19翔烁、22、5旨涝、46蹬屹。
- 第四步,根據(jù)上表,得到每個(gè)值對(duì)應(yīng)Base64編碼慨默,即T贩耐、W、F厦取、u潮太。
因此,Man的Base64編碼就是TWFu虾攻。
如果字節(jié)數(shù)不足三铡买,則這樣處理:
- 二個(gè)字節(jié)的情況:將這二個(gè)字節(jié)的一共16個(gè)二進(jìn)制位,按照上面的規(guī)則霎箍,轉(zhuǎn)成三組奇钞,最后一組除了前面加兩個(gè)0以外,后面也要加兩個(gè)0朋沮。這樣得到一個(gè)三位的Base64編碼蛇券,再在末尾補(bǔ)上一個(gè)"="號(hào)。
比如樊拓,"Ma"這個(gè)字符串是兩個(gè)字節(jié)纠亚,可以轉(zhuǎn)化成三組00010011、00010110筋夏、00010000以后蒂胞,對(duì)應(yīng)Base64值分別為T(mén)、W条篷、E骗随,再補(bǔ)上一個(gè)"="號(hào),因此"Ma"的Base64編碼就是TWE=赴叹。 - 一個(gè)字節(jié)的情況:將這一個(gè)字節(jié)的8個(gè)二進(jìn)制位鸿染,按照上面的規(guī)則轉(zhuǎn)成二組,最后一組除了前面加二個(gè)0以外乞巧,后面再加4個(gè)0涨椒。這樣得到一個(gè)二位的Base64編碼,再在末尾補(bǔ)上兩個(gè)"="號(hào)绽媒。
比如蚕冬,"M"這個(gè)字母是一個(gè)字節(jié),可以轉(zhuǎn)化為二組00010011是辕、00010000囤热,對(duì)應(yīng)的Base64值分別為T(mén)、Q获三,再補(bǔ)上二個(gè)"="號(hào)旁蔼,因此"M"的Base64編碼就是TQ==锨苏。