What is base64

Posted by Noel on 2015-06-27

在從事 web 開發時,一定常常聽到 base64,例如: rails 裡會將 cookie 值採用 base64 編碼保護,而且在 rails 使用 base64 也相當容易,如:

rails使用base64
1
2
3
4
encrypted_code = Base64.encode64 "Hello World"
# 輸出 "SGVsbG8gV29ybGQ=\n"
Base64.decode64 encrypted_code
# 輸出 "Hello World"

看起來似乎非常簡單使用跟沒什麼特別要學的成本,所以本篇教完了,結束…!?
當然沒這麼簡單,學習一項事物時,我覺得除了事物本身外, 更重要的是我們為何要學習它? 甚至去了解它的由來,我覺得對學習可以有更深的幫助,也較有趣味性。所以接下來我會講解base64的蓋要與它的使用目的。

Base64 由來:

Base64 的由來與電子郵件格式息息相關,最初在八零年代時 (1982 年 RFC822 規範文件)定義了傳統的電子郵件格式,而那時規定了只能傳輸ASCII,而這也導致了

  • 非英語字元不能在電子郵件中使用
  • 電子郵件裡不能插入二進位檔案
  • 電子郵件無法攜帶檔案附件

而為了解決這個問題,90 年代後工程師拓展了電子郵件的技術規範、並提出補充,造就了MIME的出現,以及為了轉換二進位制文件為 ASCII 字符而生的編碼,Base64 等編碼方法的出現。


Base64 介紹:

Base64 的介紹及原理在維基百科裡其實已經有詳細的講解及過程,在這我仍然簡單的介紹原理及運算並以維基百科提供的資料為參照。

Base64 的 64 的由來是由0~9+A~Z+a~z++/等 64 個字元所組成,而 64 為 2 的 6 次方,所以以 6 的位元為 1 個單位,因此如果 3 個 byte 共 24 位元長度得資料則除以 6 變成 4 個 Base64 字元,長度因此增加了 1/3 的長度。若字元長度無法被 6 整除則會再補上 0 位元,並再最後產生的結果莫段加上 1 或 2 = 字元符號(依補多少個 0 而定),因此前面才會說長度增加 大約 為 1/3。

而算法的過程為

  1. 將文字轉為 ASCII 編碼
  2. 將 ASCII 編碼轉為二進位制
  3. 以 6 個字元為一組,若長度不夠被六整除則在最右邊補上 0 字元直到可被 6 整除
  4. 得到新的以 6 個字元為長度後則在最左邊補上 2 個 0 使之轉為二進位制資料並求出值
  5. 根據該值去對 Base64 編碼做索引
  6. 若在步驟 3 有補了 4 個 0 就要在最後結果尾端補上 2 個 =,若 2 個 0 就要在最後結果尾端補上 1 個 =

範例:

Bar

  1. 66, 97, 114
  2. 01000010, 01100001, 01110010
  3. 010000, 100110, 000101, 110010
  4. 0010000(16), 00100110(38), 00000101(5), 00110010(50)
  5. Base64表後得到QmFy即為所求
  6. 步驟 3 沒有補 0 故此步驟不需要做

最終結果為Qmfy比本來的Bar長度多了 1/3。

等等

但是我們這只是用英文轉啊 ?! 好像沒有意義。如果想轉中文怎麼辦 ? 其實只有一開始多增加了一些步驟,要先根據漢字編碼如採用的是 utf-8 or GBK等不同編碼,先轉為二進位制再帶入上面的過程則可求得該漢字的 Base64 結果。

若不會把漢字依據UTF-8轉為二進位制的話,可以來這邊轉。


Base64 目的與運用:

到這裡我們對base64已經有大致了理解,base64 的主要目的就是將非 ASCII 字元轉為可列印字符,所以我們也來看看這可以適合應用在哪些地方

  • 電子郵件的格是轉換
  • 可避免二進位制檔案在網路傳輸過程中因某些格式或是協定將部分內容視為特殊符號而造成的遺漏或失真
  • HTTP 請求中可將較長的資訊編碼後放在 url 參數或表單中,同樣可避免特殊符號造成的影響
  • 隱藏資訊的可讀性(但 Base64 不能視作加密方法,因為可以被解譯)
  • Data URI (HTML 中可直接攜帶二進位制檔案,並且透過 MIME 所使用)

除了上述當然也還有其他得應用,但常見的幾個大概就是這樣,到這邊希望大家對 Base64 的使用疑惑已經解開了,如果有什麼對 Base64 的心發現或是我文章中有不對的地方都歡迎大家分享或指教~

參考

Base64笔记