寫在前面
Base64算法最早應(yīng)用于解決電子郵件傳輸問題,在早期,電子郵件只支持ASCII碼字符。如果要傳輸一封帶有非ASCII碼字符的電子郵件,當(dāng)它經(jīng)過部分網(wǎng)關(guān)時就可能出現(xiàn)問題,這個網(wǎng)關(guān)可能會對非ASCII碼字符的二進(jìn)制位進(jìn)行調(diào)整,即將這個非ASCII碼的8位二進(jìn)制碼最高位置設(shè)置為0,此時用戶收到的這個郵件就會是一封亂碼的了?;谶@個原因產(chǎn)生了Base64算法。
Base64是一種基于64個可打印字符(A-Z、a-z、0-9、+、/)來表示二進(jìn)制數(shù)據(jù)的表示方法,常用于在通常處理文本數(shù)據(jù)的場合,表示、傳輸、存儲一些二進(jìn)制數(shù)據(jù)。
原理
第一步,將每三個字節(jié)作為一組,一共是24個二進(jìn)制位。
第二步,將這24個二進(jìn)制位分為四組,每個組有6個二進(jìn)制位。
第三步,在每組前面加兩個00,擴(kuò)展成32個二進(jìn)制位,即四個字節(jié)。
第四步,這樣每個字節(jié)的轉(zhuǎn)換為十進(jìn)制的值范圍為:0-63,根據(jù)編碼表,得到擴(kuò)展后的每個字節(jié)的對應(yīng)符號,這就是Base64的編碼值。
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
比如:編碼 Man

這里有一個問題,字節(jié)數(shù)是否能被3整除。
如果要編碼的字節(jié)數(shù)不能被3整除,最后會多出1個或2個字節(jié),那么可以使用下面的方法進(jìn)行處理:先使用0字節(jié)值在末尾補(bǔ)足,使其能夠被3整除,然后再進(jìn)行Base64的編碼。在編碼后的Base64文本后加上一個或兩個=號,代表補(bǔ)足的字節(jié)數(shù)。也就是說,當(dāng)最后剩余兩個八位(待補(bǔ)足)字節(jié)(2個byte)時,最后一個6位的Base64字節(jié)塊有四位是0值,最后附加上兩個等號;如果最后剩余一個八位(待補(bǔ)足)字節(jié)(1個byte)時,最后一個6位的base字節(jié)塊有兩位是0值,最后附加一個等號。

注意:Base64是把3個字節(jié)編碼成4個字節(jié),所以編碼編碼之后的長度差不多增加了133%
關(guān)于URL安全Base64編碼
Base64編碼可用于在HTTP環(huán)境下傳遞較長的標(biāo)識信息。例如,在Java持久化系統(tǒng)Hibernate中,就采用了Base64來將一個較長的唯一標(biāo)識符(一般為128-bit的UUID)編碼為一個字符串,用作HTTP表單和HTTP GET URL中的參數(shù)。在其他應(yīng)用程序中,也常常需要把二進(jìn)制數(shù)據(jù)編碼為適合放在URL(包括隱藏表單域)中的形式。此時,采用Base64編碼不僅比較簡短,同時也具有不可讀性,即所編碼的數(shù)據(jù)不會被人用肉眼所直接看到。
然而,標(biāo)準(zhǔn)的Base64并不適合直接放在URL里傳輸,因?yàn)閁RL編碼器會把標(biāo)準(zhǔn)Base64中的/和+字符變?yōu)樾稳?XX的形式,而這些%號在存入數(shù)據(jù)庫時還需要再進(jìn)行轉(zhuǎn)換,因?yàn)锳NSI SQL中已將%號用作通配符。
為解決此問題,可采用一種用于URL的改進(jìn)Base64編碼,它不在末尾填充=號,并將標(biāo)準(zhǔn)Base64中的+和/分別改成了-和_,這樣就免去了在URL編解碼和數(shù)據(jù)庫存儲時所要做的轉(zhuǎn)換,避免了編碼信息長度在此過程中的增加,并統(tǒng)一了數(shù)據(jù)庫、表單等處對象標(biāo)識符的格式。