所有字符均可打印的編碼方式
基本介紹
「Base64」 是一種基於 64 個可打印字符來表示二進制數據的表示方法。由於 「2⁶ = 64」 ,所以每 6 個比特為一個單元,對應某個可打印字符。(回顧一下,我們之前介紹的 ASCII/Unicode 編碼裏都有不可打印字符)
體驗效果請戳這裏 👉:Base64 編碼/解碼
Base64 相應的索引表如下(這與 ASCII/Unicode 完全不同):
3 個字節有 24 個比特,對應於 4 個 base64 單元,即 3 個字節可由 4 個可打印字符來表示。
相應的轉換過程如下圖所示:
編碼過程詳解
瞭解完上述的知識,我們以編碼 Man 為例,來直觀的感受一下編碼過程。
找到 ASCII 對應,轉換成二進制表示
Man 由 M、a 和 n 這 3 個字符組成,它們對應的 ASCII 碼為 77、97 和 110。
每 6 個比特為一個單元,進行 base64 編碼
接着我們以每 6 個比特為一個單元,進行 base64 編碼操作,具體如下圖所示:
由圖可知,Man (3 字節)編碼的結果為 TWFu(4 字節),很明顯經過 base64 編碼後體積會增加 1/3。Man 這個字符串的長度剛好是 3,我們可以用 4 個 base64 單元來表示。
但如果待編碼的字符串長度不是 3 的整數倍時,應該如何處理呢?
處理字節數不能被 3 整除的情況
「如果要編碼的字節數不能被 3 整除,最後會多出 1 個或 2 個字節,那麼可以使用下面的方法進行處理:先使用 0 字節值在末尾補足,使其能夠被 3 整除,然後再進行 base64 的編碼。」
以編碼字符 A 為例,其所佔的字節數為 1,不能被 3 整除,需要補 2 個字節,具體如下圖所示:
由上圖可知,字符 A 經過 base64 編碼後的結果是 QQ==,該結果後面的兩個 = 代表補足的字節數。而最後個 1 個 base64 字節塊有 4 位是 0 值。
接着我們來看另一個示例,假設需編碼的字符串為 BC,其所佔字節數為 2,不能被 3 整除,需要補 1 個字節,具體如下圖所示:
由上圖可知,字符串 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
對於 atob 和 btoa 這兩個方法來説,其中的 a 代表 ASCII,而 b 代表 Blob,即二進制。
- 因此 atob 表示 ASCII 到二進制,對應的是解碼操作。
- 而 btoa 表示二進制到 ASCII,對應的是編碼操作。
在瞭解方法中 a 和 b 分別代表的意義之後,在以後的工作中,我們就不會用錯了。
應用
「Base64 常用於在處理文本數據的場合,表示、傳輸、存儲一些二進制數據,包括 MIME 的電子郵件及 XML 的一些複雜數據。」
在 MIME 格式的電子郵件中,base64 可以用來將二進制的字節序列數據編碼成 ASCII 字符序列構成的文本。使用時,在傳輸編碼方式中指定 base64。使用的字符包括大小寫拉丁字母各 26 個、數字 10 個、加號 + 和斜槓 /,共 64 個字符,等號 = 用來作為後綴用途。
其實我們常用的 jwt 技術也應用到了 base64 編碼:
在獲取圖像內容時也經常用到 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
總結
- base64 只是一種數據編碼方式,目的是為了保障數據的安全傳輸。
- Base64編碼會增加數據的大小,大約會增加33%
- 標準的 base64 編碼無需額外的信息,即可以進行解碼,是完全可逆的。因此在涉及傳輸私密數據時,並不能直接使用 base64 編碼,而是要使用專門的對稱或非對稱加密算法。
參考資料
- https://juejin.cn/post/6846687590783909902