在前文 Data URI 應用場景小結 中我們提到了一個概念,叫做 base64編碼,今天我們就來聊聊 base64編碼,揭開它的神秘面紗。
一句話解釋:Base64是一種基於64個可打印字符來表示二進制數據的表示方法。
用記事本打開 exe
、jpg
、pdf
這些文件時,我們都會看到一大堆亂碼,因為二進制文件包含很多無法顯示和打印的字符,所以,如果要讓記事本這樣的文本處理軟件能處理二進制數據,就需要一個二進制到字符串的轉換方法。Base64 是一種最常見的二進制編碼方法。
Base64的原理很簡單,首先,准備一個包含 64 個字符的數組:
['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
附 base64 索引表:
然后,對二進制數據進行處理,每 3 個字節一組(如果字節數不能被 3 整除,則用 0 補位),每個字節是 8 bits,一共是 3 x 8 = 24 bits
,划為 4 組,每組正好 6 個 bits。將每組的 6 bits 轉為十進制數字,這樣我們得到 4 個數字作為索引(3->4,所以經過 base64 編碼的圖片會比原文件大 1/3,不過一般經過 gzip 壓縮后跟原文件大小差不多),然后查表,獲得相應的 4 個字符,就是編碼后的字符串。
如果是字符串的 base64 編碼,具體步驟為:
- 獲取字符串每個字符的 ASCII 碼,如果字符數不能被 3 整除,則末尾補 0
- 將步驟 1 獲取的 ASCII 碼轉為 8 位 二進制碼
- 每 6 bits 為一組,並將 6 位二進制碼轉為十進制
- 對照上面的 base64 索引表,得到編碼后的字符串
需要注意的是:
- 要求被編碼字符是 8bit 的,所以須在 ASCII 編碼范圍內,\u0000-\u00ff,中文就不行
- 如果被編碼字符長度不是 3 的倍數的時候,則都用 0 代替,對應的輸出字符為 =,而不是查表所得的 A(所以通過 base64編碼 的圖片最后有時會有 1-2 個 =)
舉兩個例子:
(1)字符長度能被 3 整除時,比如 'han':
h a n
ASCII 104 97 110
8bit字節 01101000 01100001 01101110
6bit字節 011010 000110 000101 101110
十進制 26 6 5 46
對應編碼 a G F u
(2)字符長度不能被 3 整除時,比如 'zichi':
z i c h i
ASCII: 122 105 99 104 105
8bit字節: 01111010 01101001 01100011 01101000 01101001 00000000(補)
6bit字節: 011110 100110 100101 100011 011010 000110 100100 000000
十進制: 30 38 37 35 26 6 36 異常
對應編碼: e m l j a G k =
事實上,高級瀏覽器已經內置了 atob
(ASCII to Binary)以及 btoa
(Binary to ASCII)函數分別用來處理解碼和編碼 base64 字符串。atob() 函數能夠解碼通過 base-64 編碼的字符串數據。相反地,btoa() 函數能夠從二進制數據“字符串”創建一個 base-64 編碼的 ASCII 字符串。(PS:特別要注意的是 btoa 是編碼,atob 是解碼 o(╯□╰)o)
不幸的是某些版本的 IE 瀏覽器並不支持 atob() 以及 btoa() 函數,好在理解了上述的編碼步驟,一個 base64編碼、轉碼器也就不難實現了,可以猛戳 DEMO 進行查看(HTML 部分 fork 了岑安大大的代碼,把 select 改成了 radio,個人覺得 radio 更方便)。代碼放在了 Github。
Read More: