java加密、解密技術系列:Base64

斌斌 (給我寫信) 原創博文(http://blog.csdn.net/binbinxyz),轉載請註明出處

一. 背景

最近一段時間,我在學習比特幣、區塊鏈相關的技術。我在裡面見到了很多加解密的技術,比如橢圓曲線加密演算法、Base58編碼演算法、SHA256雜湊演算法、RIPEMD-160雜湊演算法等。本著學習的態度,我打算花時間好好研究一下這些技術,看看這些加解密技術到底在幹什麼?又能幹什麼?同時,我也想記錄下自己的學習歷程,一方面算是為自己留下點什麼,另一方面也算是督促自己進步吧!

二. 引言

學習比特幣,接觸最多的肯定要屬比特幣地址了。它是一長串的字母和數字組合,例如:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。其實,比特幣的地址使用了一種變形的Base64編碼(實際是Base58編碼)。Base64是網路上最常見的用於傳輸的編碼方式之一,那麼,我們就從研究Base64開始吧!

三. 正文

其實,嚴格來說,Base64是一種編碼方式,並不是真正意義上的加密解密。不過,它也是把資料變為人不會用肉眼能分辨其真實性的角度來說。如果從這個角度來考慮的話,它也屬於加密解密的範疇。
那麼,Base64是什麼東東呢?根據RFC2045的定義,Base64的定義是:Base64內容傳送編碼被設計用來把任意序列的8位位元組描述為一種不易被人直接識別的形式。(#6.8>Base64 Content-Transfer-Encoding: The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)

四. 編碼原理

1. 編碼

Base64編碼按字串長度進行處理。
1. 每3個8bit的字元分為一組。
2. 針對每組,先獲取每個字元的ASCII編碼,得到3個ASCII編碼。
3. 將ASCII編碼轉換成8bit的二進位制,得到一組二進位制位元組,長度是3*8=24bit。
4. 將24bit劃分為4個6bit的位元組,並在每個6bit的位元組前面填充兩個高位0,得到4個8bit的位元組。
5. 將這4個8bit的位元組轉換成十進位制。
6. 對照Base64編碼表(參考表一),得到對應編碼字元。
7. 依次將各組查表所得字元合並即得到編碼結果。
表一 Base64編碼表

ValueEncodingValueEncodingValueEncodingValueEncoding
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62
15P31f47v63/

2. 填充

如果編碼的位元組數不能被三整除(即如果最後24位位元組的輸入只有一個或兩個位元組),進行以下處理:用零值填充額外的位元組,以達到三位元組,然後執行Base64轉換。如果輸入只有一個位元組,只有前兩個Base64位有值(12bits);如果輸入只有兩個位元組,只有前三個Base64位有值(18bits)。字元’=’可能被填充到最後一塊以滿足四個Base64位。
“==”表示最後一組只包含一個位元組,”=”表示最後一組包含兩個位元組。

3.解碼

學會了編碼,我想你肯定也和我一樣早就知道怎樣解碼了吧?是的,解碼過程其實就是一個反向的編碼過程,這裡就不再贅述啦~

五.示例

1. 例一

字元cat長度能被3整除,所以Base64(cat)=Y2F0。也就是說,cat的 Base64編碼結果為Y2F0。
Base64(cat)

2. 例二

字元home長度不能被3整除。由於home只有4個字母,所以按3個一組的話,第二組還有兩個空位,所以需要用0來填充。需要注意,因為是需要填充而出現的0,所以轉化成十進位制的時候就不能按常規用Base64編碼表來對應,所以結尾不是a,而是=。
Base64(home)

六. 結語

通過學習上面記錄的這些內容,我已經充分了解了Base64的編碼原理,你肯定也都懂了吧?如果你再用自己熟悉的任何語言編寫一個程式來實現上述編碼、解碼過程,那麼你一定會印象更加深刻的。

七. 參考文獻

  1. wiki Base64: https://en.wikipedia.org/wiki/Base64
  2. RFC2045: https://tools.ietf.org/html/rfc2045
  3. The Base16, Base32, and Base64 Data Encodings: https://tools.ietf.org/html/rfc4648
  4. org.apache.commons.codec.binary.Base64: http://commons.apache.org/proper/commons-codec/