博客 / 詳情

返回

字符編碼系列: base64

所有字符均可打印的編碼方式

基本介紹

「Base64」 是一種基於 64 個可打印字符來表示二進制數據的表示方法。由於 「2⁶ = 64」 ,所以每 6 個比特為一個單元,對應某個可打印字符。(回顧一下,我們之前介紹的 ASCII/Unicode 編碼裏都有不可打印字符)
體驗效果請戳這裏 👉:Base64 編碼/解碼

Base64 相應的索引表如下(這與 ASCII/Unicode 完全不同):
image.png

3 個字節有 24 個比特,對應於 4 個 base64 單元,即 3 個字節可由 4 個可打印字符來表示
相應的轉換過程如下圖所示:
image.png

編碼過程詳解

瞭解完上述的知識,我們以編碼 Man 為例,來直觀的感受一下編碼過程。

找到 ASCII 對應,轉換成二進制表示

Man 由 M、a 和 n 這 3 個字符組成,它們對應的 ASCII 碼為 77、97 和 110。
image.png

每 6 個比特為一個單元,進行 base64 編碼

接着我們以每 6 個比特為一個單元,進行 base64 編碼操作,具體如下圖所示:
image.png

由圖可知,Man (3 字節)編碼的結果為 TWFu(4 字節),很明顯經過 base64 編碼後體積會增加 1/3。Man 這個字符串的長度剛好是 3,我們可以用 4 個 base64 單元來表示。
但如果待編碼的字符串長度不是 3 的整數倍時,應該如何處理呢?

處理字節數不能被 3 整除的情況

「如果要編碼的字節數不能被 3 整除,最後會多出 1 個或 2 個字節,那麼可以使用下面的方法進行處理:先使用 0 字節值在末尾補足,使其能夠被 3 整除,然後再進行 base64 的編碼。」
以編碼字符 A 為例,其所佔的字節數為 1,不能被 3 整除,需要補 2 個字節,具體如下圖所示:
image.png

由上圖可知,字符 A 經過 base64 編碼後的結果是 QQ==,該結果後面的兩個 = 代表補足的字節數。而最後個 1 個 base64 字節塊有 4 位是 0 值。
接着我們來看另一個示例,假設需編碼的字符串為 BC,其所佔字節數為 2,不能被 3 整除,需要補 1 個字節,具體如下圖所示:

image.png

由上圖可知,字符串 BC 經過 base64 編碼後的結果是 QkM=,該結果後面的 1 個 = 代表補足的字節數。而最後個 1 個 base64 字節塊有 2 位是 0 值。

在 JavaScript 中處理解碼和編碼

在 JavaScript 中,有兩個函數被分別用來處理解碼和編碼 base64 字符串:

  • btoa():該函數能夠基於二進制數據 “字符串” 創建一個 base64 編碼的 ASCII 字符串。
  • atob(): 該函數能夠解碼通過 base64 編碼的字符串數據。

btoa 使用示例

const name = 'Semlinker';
const encodedName = btoa(name);
console.log(encodedName); // U2VtbGlua2Vy

atob 使用示例

const encodedName = 'U2VtbGlua2Vy';
const name = atob(encodedName);
console.log(name); // Semlinker

對於 atobbtoa 這兩個方法來説,其中的 a 代表 ASCII,而 b 代表 Blob,即二進制。

  • 因此 atob 表示 ASCII 到二進制,對應的是解碼操作。
  • 而 btoa 表示二進制到 ASCII,對應的是編碼操作。

在瞭解方法中 a 和 b 分別代表的意義之後,在以後的工作中,我們就不會用錯了。

應用

Base64 常用於在處理文本數據的場合,表示、傳輸、存儲一些二進制數據,包括 MIME 的電子郵件及 XML 的一些複雜數據。」
MIME 格式的電子郵件中,base64 可以用來將二進制的字節序列數據編碼成 ASCII 字符序列構成的文本。使用時,在傳輸編碼方式中指定 base64。使用的字符包括大小寫拉丁字母各 26 個、數字 10 個、加號 + 和斜槓 /,共 64 個字符,等號 = 用來作為後綴用途。

其實我們常用的 jwt 技術也應用到了 base64 編碼:
image.png

在獲取圖像內容時也經常用到 base 64:

// 使用 canvas 繪製內容
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d')
...
// 把 canvas 內容轉化成 base64 圖片形式
const img = canvas.toDataURL()
// do something
// 比如 web 展示、截圖分享、微信分享等

圖片結構:
data:image/png;base64,xxxxxxxxx

總結

  1. base64 只是一種數據編碼方式,目的是為了保障數據的安全傳輸。
  2. Base64編碼會增加數據的大小,大約會增加33%
  3. 標準的 base64 編碼無需額外的信息,即可以進行解碼,是完全可逆的。因此在涉及傳輸私密數據時,並不能直接使用 base64 編碼,而是要使用專門的對稱或非對稱加密算法。

參考資料

  1. https://juejin.cn/post/6846687590783909902
user avatar huishou 頭像 ziyeliufeng 頭像 sunhengzhe 頭像 user_p5fejtxs 頭像 mrqueue 頭像 gfeteam 頭像 tofrankie 頭像 clearlove07 頭像 jidongdemogu 頭像 xiaohuoche 頭像 kandole 頭像 geoffzhu 頭像
18 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.