Base64

Base64是網絡上最常見的用於傳輸8Bit字節代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規範。

Base64要求把每三個8Bit的字節轉換爲四個6Bit的字節(3*8 = 4*6 = 24),然後把6Bit再添兩位高位0,組成四個8Bit的字節,也就是說,轉換後的字符串理論上將要比原來的長1/3。

這樣說會不會太抽象了?不怕,我們來看一個例子:

轉換前 aaaaaabb ccccdddd eeffffff
轉換後 00aaaaaa 00bbcccc 00ddddee 00ffffff

應該很清楚了吧?上面的三個字節是原文,下面的四個字節是轉換後的Base64編碼,其前兩位均爲0。

轉換後,我們用一個碼錶來得到我們想要的字符串(也就是最終的Base64編碼),這個表是這樣的:(摘自RFC2045)

            Table 1: The Base64 Alphabet

   Value Encoding   Value Encoding   Value Encoding   Value Encoding
          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       (pad) =
      15 P          32 g          49 x
      16 Q          33 h          50 y

讓我們再來看一個實際的例子,加深印象!

轉換前 10101101 10111010 01110110
轉換後 00101011 00011011 00101001 00110110
十進制 43 27 41 54
對應碼錶中的值 r b p 2


所以上面的24位編碼,編碼後的Base64值爲 rbp2
解碼同理,把 rbq2 的二進制位連接上再重組得到三個8位值,得出原碼。
(解碼只是編碼的逆過程,在此我就不多說了,另外有關MIME的RFC還是有很多的,如果需要詳細情況請自行查找。)

用更接近於編程的思維來說,編碼的過程是這樣的:

第一個字符通過右移2位獲得第一個目標字符的Base64表位置,根據這個數值取到表上相應的字符,就是第一個目標字符。
然後將第一個字符左移4位加上第二個字符右移4位,即獲得第二個目標字符。
再將第二個字符左移2位加上第三個字符右移6位,獲得第三個目標字符。
最後取第三個字符的右6位即獲得第四個目標字符。

在以上的每一個步驟之後,再把結果與 0x3F 進行 AND 位操作,就可以得到編碼後的字符了。

可是等等……聰明的你可能會問到,原文的字節數量應該是3的倍數啊,如果這個條件不能滿足的話,那該怎麼辦呢?

我們的解決辦法是這樣的:原文的字節不夠的地方可以用全0來補足,轉換時Base64編碼用=號來代替。這就是爲什麼有些Base64編碼會以一個或兩個等號結束的原因,但等號最多隻有兩個。因爲:

餘數 = 原文字節數 MOD 3

所以餘數任何情況下都只可能是0,1,2這三個數中的一個。如果餘數是0的話,就表示原文字節數正好是3的倍數(最理想的情況啦)。如果是1的話,爲了讓Base64編碼是4的倍數,就要補2個等號;同理,如果是2的話,就要補1個等號。
在線轉換:http://md5.mmkey.com/base64/

Java code
import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;public class Test {            public static void main(String args[]) throws IOException {        BASE64Encoder encode = new BASE64Encoder();        String base64 = encode.encode("五筆字型電子計算機".getBytes());        System.out.println(base64);                BASE64Decoder decode = new BASE64Decoder();        byte[] b = decode.decodeBuffer(base64);        System.out.println(new String(b));    }}輸出:

zuWxytfW0M2159fTvMbL47v6
五筆字型電子計算機
JRE 中 sun 和 com.sun 開頭包的類都是未被文檔化的,他們屬於 java, javax
類庫的基礎,其中的實現大多數與底層平臺有關,一般來說是不推薦使用的。

Base64 主要不是加密,它主要的用途是把一些二進制數轉成普通字符用於網絡傳輸。
由於一些二進制字符在傳輸協議中屬於控制字符,不能直接傳送需要轉換一下就可以了。


// 將 s 進行 BASE64 編碼
public static String getBASE64(String s) {
if (s == null) return null;
return (new sun.misc.BASE64Encoder()).encode( s.getBytes() );
}

// 將 BASE64 編碼的字符串 s 進行解碼
public static String getFromBASE64(String s) {
if (s == null) return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}

發佈了41 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章