Base64編碼解碼算是網(wǎng)絡(luò)安全領(lǐng)域的很小而且很簡(jiǎn)單的一個(gè)知識(shí)點(diǎn)了党瓮,雖然簡(jiǎn)單但是應(yīng)用場(chǎng)景卻極其廣泛萤捆,可以這樣說(shuō)叹哭,開發(fā)者要是不懂Base64谷羞,基本上可以告別程序猿生涯了帝火。這篇文章從原理入手,并給出java的Base64實(shí)現(xiàn)湃缎。方便你掌握Base64犀填。
一、Base64由來(lái)
很早之前嗓违,電子郵件剛剛問(wèn)世九巡,那時(shí)候消息的傳遞都是英文,后來(lái)中國(guó)開通了互聯(lián)網(wǎng)之后蹂季,對(duì)郵件的使用量也大量增加冕广,這時(shí)候電子郵件就有了中文的需求疏日。但是中文在傳輸?shù)臅r(shí)候不能被有效地處理,這時(shí)候Base就出來(lái)了撒汉,Base64通過(guò)對(duì)這些中文進(jìn)行編碼沟优,轉(zhuǎn)化為服務(wù)器和網(wǎng)關(guān)能夠識(shí)別的數(shù)據(jù)。這時(shí)候就能夠使用電子郵件有效地傳輸了睬辐。
上面的這個(gè)例子不是說(shuō)Base64專門為電子郵件而生的挠阁,從其誕生之初,就開始在各大領(lǐng)域有了廣泛的應(yīng)用溯饵。比如說(shuō)網(wǎng)絡(luò)上傳遞圖片侵俗,我們可以Base64先對(duì)圖片進(jìn)行處理,然后就可以有效的傳輸了丰刊。
OK隘谣,我們大致知道其用途,然后我們就好好的分析一下他的原理藻三,到底是如何對(duì)這些數(shù)據(jù)進(jìn)行編碼的洪橘。
二、Base64原理
1棵帽、Base64編碼
Base64的原理超級(jí)簡(jiǎn)單熄求,相信我們都知道ASCII 編碼,從A-Z逗概、a-z弟晚、0-9和一些其他的特殊字符,這些字符都有唯一的一個(gè)數(shù)字來(lái)表示逾苫。比如說(shuō)a是97卿城,A是65。我們來(lái)截取一部分圖看一下:
同理Base64也有這樣一套編碼铅搓。范圍是”A-Z“瑟押、”a-z“、”0-9“星掰、”+“多望、”/“一共64個(gè)字符。我們給出一個(gè)表格來(lái)看一下氢烘,這個(gè)比ASCII編碼要簡(jiǎn)單多了怀偷,只有64個(gè)。
索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 |
---|---|---|---|---|---|---|---|
0 | A | 17 | R | 34 | i | 51 | z |
1 | B | 18 | S | 35 | j | 52 | 0 |
2 | C | 19 | T | 36 | k | 53 | 1 |
3 | D | 20 | U | 37 | l | 54 | 2 |
4 | E | 21 | V | 38 | m | 55 | 3 |
5 | F | 22 | W | 39 | n | 56 | 4 |
6 | G | 23 | X | 40 | o | 57 | 5 |
7 | H | 24 | Y | 41 | p | 58 | 6 |
8 | I | 25 | Z | 42 | q | 59 | 7 |
9 | J | 26 | a | 43 | r | 60 | 8 |
10 | K | 27 | b | 44 | s | 61 | 9 |
11 | L | 28 | c | 45 | t | 62 | + |
12 | M | 29 | d | 46 | u | 63 | / |
13 | N | 30 | e | 47 | v | ||
14 | O | 31 | f | 48 | w | ||
15 | P | 32 | g | 49 | x | ||
16 | Q | 33 | h | 50 | y |
由于索引是從0開始播玖,所以最后的索引是63椎工。在編碼的時(shí)候Base64就是通過(guò)上面的進(jìn)行轉(zhuǎn)換編碼的。下面我們就來(lái)看看Base64編碼的原理。
2维蒙、基本原理
比如說(shuō)有一封郵件掰吕,我們想要對(duì)其使用Base64進(jìn)行編碼。怎么辦呢木西?基本步驟如下:
(1)對(duì)郵件的數(shù)據(jù)進(jìn)行切分畴栖,每三個(gè)字節(jié)一組,一共24個(gè)bit八千。
(2)對(duì)切分后的數(shù)據(jù)重組吗讶,24個(gè)bit重組為4組,每組6個(gè)bit恋捆。
(3)對(duì)重組后的數(shù)據(jù)處理照皆,每組最前面添加兩個(gè)“0”,構(gòu)成每組8個(gè)bit沸停。此時(shí)一共32個(gè)bit膜毁。
(4)根據(jù)Base64編碼表,獲取相應(yīng)的編碼值愤钾。
此時(shí)一封完整的郵件瘟滨,被切分重組處理之后就變成了Base64編碼了∧馨洌基本原理其實(shí)很簡(jiǎn)單杂瘸。不過(guò)你不理解也沒(méi)關(guān)系,我們直接上個(gè)實(shí)例來(lái)解釋一下伙菊。
3败玉、實(shí)例驗(yàn)證
比如說(shuō)電子郵件里面出現(xiàn)了三個(gè)字母sky。我們要對(duì)這個(gè)三個(gè)字符使用Base64進(jìn)行編碼镜硕。
(1)對(duì)郵件的數(shù)據(jù)進(jìn)行切分运翼,每三個(gè)字節(jié)一組,一共24個(gè)bit
數(shù)據(jù) | s | k | y |
---|---|---|---|
ASCII編碼 | 115 | 107 | 121 |
二進(jìn)制 | 01110011 | 01101011 | 01111001 |
(2)對(duì)切分后的數(shù)據(jù)重組兴枯,24個(gè)bit重組為4組血淌,每組6個(gè)bit
(3)對(duì)重組后的數(shù)據(jù)處理,每組最前面添加兩個(gè)“0”财剖,構(gòu)成每組8個(gè)bit悠夯。由于在最前面添加的0,所以對(duì)數(shù)值不構(gòu)成影響峰伙。
(4)根據(jù)Base64編碼表疗疟,獲取相應(yīng)的編碼值
(5)完成編碼的轉(zhuǎn)換
到這我們基本上就是實(shí)現(xiàn)了Base64編碼機(jī)制從sky到c2t5的轉(zhuǎn)換该默。
有些地方需要我們?nèi)プ⒁庖幌拢?/strong>
(1)在第三步中瞳氓,最前面添加了兩個(gè)0,所以最終編碼之后要比之前多出三分之一的大小。
(2)上面的例子中匣摘,我們使用的是ASCII編碼店诗,但是如果我們使用UTF-8,對(duì)應(yīng)Base64編碼的結(jié)果是不一樣的音榜。
(3)Base64只是進(jìn)行了編碼庞瘸,方便數(shù)據(jù)的傳輸而已。這可不是加密赠叼。
原理也搞清楚了擦囊,現(xiàn)在我們就實(shí)現(xiàn)一下。
三嘴办、代碼實(shí)現(xiàn)
你可以自己去實(shí)現(xiàn)一個(gè)編碼解碼的完整過(guò)程瞬场,但是java已經(jīng)為我們封裝好了,我們直接只用別人造好的輪子多好涧郊。不管是自己寫還是使用別人的贯被,原理搞清楚就OK了。
public class Test {
public static void main(String[] args) throws IOException {
String str = "sky";
//編碼
BASE64Encoder encoder = new BASE64Encoder();
String encoderResult=encoder.encode(str.getBytes());
System.out.println("編碼結(jié)果為:" + encoderResult);
//解碼
BASE64Decoder decoder = new BASE64Decoder();
byte[] decoderResult=decoder.decodeBuffer(encoderResult);
System.out.println("解碼結(jié)果為:" + new String(decoderResult));
}
}
//編碼結(jié)果為:c2t5
//解碼結(jié)果為:sky
是不是很簡(jiǎn)單妆艘。其實(shí)java實(shí)現(xiàn)的方式有很多種彤灶,其他的還有Commons Codec和Bouncy Castle。實(shí)現(xiàn)的過(guò)程和JDK提供的類似批旺,我們只需要導(dǎo)入相應(yīng)的jar包即可幌陕。
Base64算法的應(yīng)用場(chǎng)景有E-Mail、密鑰朱沃、證書文件等等苞轿。這也只是入門,想要深入了解逗物,可以看一些安全有關(guān)的書籍搬卒,不過(guò)很多都和數(shù)學(xué)有關(guān),看的實(shí)在是難受翎卓,曾經(jīng)看過(guò)契邀,可惜沒(méi)堅(jiān)持住。慚愧失暴,書到用時(shí)方恨少坯门。
OK。有問(wèn)題還請(qǐng)指正逗扒。