關於base64編碼的原理和實現


在前文 Data URI 應用場景小結 中我們提到了一個概念,叫做 base64編碼,今天我們就來聊聊 base64編碼,揭開它的神秘面紗。

一句話解釋:Base64是一種基於64個可打印字符來表示二進制數據的表示方法。

用記事本打開 exejpgpdf 這些文件時,我們都會看到一大堆亂碼,因為二進制文件包含很多無法顯示和打印的字符,所以,如果要讓記事本這樣的文本處理軟件能處理二進制數據,就需要一個二進制到字符串的轉換方法。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 編碼,具體步驟為:

  1. 獲取字符串每個字符的 ASCII 碼,如果字符數不能被 3 整除,則末尾補 0
  2. 將步驟 1 獲取的 ASCII 碼轉為 8 位 二進制碼
  3. 每 6 bits 為一組,並將 6 位二進制碼轉為十進制
  4. 對照上面的 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:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM