首頁 > 軟體

Base64 編碼原理

2021-02-09 11:00:28

什麼是 Base64 編碼

Base64 編碼是最常見的編碼方式,基於 64 個可列印字元來表示任意二進位制資料的方法,是從二進位制轉換到可見字元的過程。

使用場景

資料加密或簽名通過 Base64 轉換為字串儲存或傳輸。
不能傳輸檔案的網路環境可以轉換 Base64 進行網路傳輸。
在文字資源(如 HTML 和 CSS檔案)中嵌入圖片檔案或其他二進位制資源。
在 URL、網頁中傳輸少量二進位制資料等等。

Base64 編碼原理

原理是把每 3 個位元組(每個位元組為 8 位, 3 個位元組為 24 位)重新劃為 4 組(每組為 6位,高位補兩個 0 為 8 位後作為一個新位元組,劃分後的每個位元組數值的範圍是 00000000 - 00111111 即十進位制的 0 - 63),然後將劃分後的位元組的數值作為索引查編碼表,獲得相應的字元,從而得到編碼後的字串。通過 64 個字元來對任意資料進行編碼,因此稱為 Base64。

Base64 標準編碼表:

以字串 「NEW」 為例,對其 Base64 編碼:

如果要編碼的位元組數不能被 3 整除,最後會多出 1 個或 2 有效的位元組。將這樣處理,將其用 0 補充至 6 的最小倍數位後,剩餘的空位將使用 「=」 填充處理。例如:


經過 Base64 編碼後資料會增大,資料經過 Base64 處理後,由原來每 3 個位元組,變為為 4 個位元組,資料大小會變為原來的 4/3, 因此資料增大 1/3。

對於字元內容,相同字串不同的字元編碼(如 utf-8 與 gbk)的 Base64 編碼結果會不一樣。Base64 是一種通過查表的編碼方法,不能用於加密,即使是自定義編碼表也不行。

JDK 內建的 Base64 API

在 JDK 7 之前可以使用 sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder 來 Base64 編碼解碼,但 com.sun 開頭的包不是公開的,屬於 sun 的內部方法,不建議使用。所以可以使用 Apache 提供的工具包(commons-codec-1.11.jar)來進行 Base64 編碼解碼。

從 JDK 7 開始 Oracle 發表了宣告,不希望 Java 程式呼叫 JDK 系統包中以 sun 開頭的類(https://www.oracle.com/technetwork/java/faq-sun-packages-142232.html)。

從 JKD 8 開始,Oracle 已經把 Base64 進行優化並放到 JDK 的 java.util 包,所以推薦直接使用 java.util.Base64 進行 Base64 編碼和解碼。

// Base64 編碼
String encoder = Base64.getEncoder().encodeToString("但願人長久 千里共嬋娟".getBytes());
System.err.println(encoder);		

// Base64 解碼
String decoder = new String(Base64.getDecoder().decode(encoder));
System.err.println(decoder);

// 結果
// 5L2G5oS/5Lq66ZW/5LmFIOWNg+mHjOWFseWpteWonw==
// 但願人長久 千里共嬋娟

標準的 Base64 編碼中可能出現字元 + 和 / 字元,不能直接用在 URL 中,需要對其進行處理,把字元 + 和 / 分別變成 - 和 _ ,JDK 也提供了對應的方法。

// URL安全的 Base64 編碼
String safeEncoder = Base64.getUrlEncoder().encodeToString("但願人長久 千里共嬋娟".getBytes());
System.err.println(safeEncoder);	

// URL安全的 Base64 解碼
String safeDecoder = new String(Base64.getUrlDecoder().decode(safeEncoder));
System.err.println(safeDecoder);

// 結果
// 5L2G5oS_5Lq66ZW_5LmFIOWNg-mHjOWFseWpteWonw==
// 但願人長久 千里共嬋娟

小結

Base64 是基於 64 個可列印字元來表示任意二進位制資料的方法。

Base64 通常用於資料加密或簽名後轉換為可見字串,文字資源(如 HTML 和 CSS 中)中嵌入圖片檔案等等。

原理是把二進位制資料每 3 個位元組重新劃為 4 組(每三個 8 位位元組,即總共24位元,可以由四個 6 位 Base64 數值表示),然後作為索引查編碼表,獲得相應的字元,從而得到編碼後的字串。

經過 Base64 編碼後資料會增大,因為每 3 個位元組,重新劃分為 4 個位元組,資料大小會變為原來的 4/3, 因此資料增大 1/3。

Base64 是一種通過索引查表的編碼方法,不能用於加密。


參考:
https://en.wikipedia.org/wiki/Base64
https://www.ietf.org/rfc/rfc4648.txt
https://www.liaoxuefeng.com/wiki/897692888725344/949441536192576


IT145.com E-mail:sddin#qq.com