1. 程式人生 > 實用技巧 >Base64編碼的前世今生

Base64編碼的前世今生

Base64是一種基於64個可列印字元來表示二進位制資料的表示方法。由於2的6次方等於64,所以每6個位元為一個單元,對應某個可列印字元。三個位元組有24個位元,對應於4個Base64單元,即3個位元組可表示4個可列印字元。它可用來作為電子郵件的傳輸編碼。在Base64中的可列印字元包括字母A-Z、a-z、數字0-9,這樣共有62個字元,此外兩個可列印符號在不同的系統中而不同。一些如uuencode的其他編碼方法,和之後binhex的版本使用不同的64字符集來代表6個二進位制數字,但是它們不叫Base64。

起因

計算機以二進位制形式(0和1)進行通訊,但是人們通常希望與更豐富的表單資料(例如文字或影象)進行通訊。 為了在計算機之間傳輸此資料,首先必須將其編碼為0和1,然後傳送,然後再次解碼。 以文字為例-有許多不同的方法可以執行此編碼。 如果我們都可以同意一個編碼,那就簡單得多了,但不幸的是事實並非如此。

最初建立了許多不同的編碼(例如Baudot碼),每個字元使用不同數量的位,直到最終ASCII成為每個字元7位的標準。 但是,大多數計算機將二進位制資料儲存在每個位元組由8位組成的位元組中,因此ASCII不適合傳輸此類資料。 有些系統甚至會擦除最高位。 此外,跨系統的行尾編碼的差異意味著有時還會修改ASCII字元10和13。
為了解決這些問題,引入了Base64編碼。 這樣,您就可以將框架位元組編碼為已知可以安全傳送而不損壞的位元組(ASCII字母數字字元和幾個符號)。 缺點是使用Base64編碼訊息會增加其長度-每3個位元組的資料會編碼為4個ASCII字元。
為了可靠地傳送文字,您可以首先使用所選的文字編碼(例如UTF-8)將其編碼為位元組,然後再對Base64進行編碼,將生成的二進位制資料編碼為可安全傳送為ASCII的文字字串。 接收者將不得不逆轉此過程以恢復原始訊息。 當然,這要求接收者知道使用了哪種編碼,並且該資訊通常需要單獨傳送。
從歷史上看,它已用於對電子郵件中的二進位制資料進行編碼,其中電子郵件伺服器可能會修改行尾。 一個更現代的示例是使用Base64編碼將影象資料直接嵌入HTML原始碼中。 在這裡,有必要對資料進行編碼,以避免像“ <”和“>”這樣的字元被解釋為標籤。

原理

base64 加密原理,是將待轉換字串轉換為二進位制並以三個字為一組(資料不足用 0 補足),每 6 位為一個索引組轉換為十進位制索引,通過索引在 base64 索引表中找到對應的字元作為編碼後的字元(若原資料長度不是 3 的倍數時則對 3 取余余數為 1,則在編碼結果後加2個=;若餘數為 2,則在編碼結果後加 1 個 =。)。

轉換流程
base64索引表

base64 轉換例項

以 helloworld 為例轉換過程如下:
base64轉換例項
經過上述步驟轉後字串為:aGVsbG93d29ybGQ=,到此一個完整的轉碼例子便完成了。

應用

base64 在需要網路通訊的場景下,有著非常廣泛的應用場景,比如郵件的附件和圖象傳輸,html img 標籤的 src 屬性也可以是 base64 編碼的圖片,還有我們常用的各類證書(支付證書,ssl 證書)的公鑰和私鑰…

Summary

base64 是一個很優秀的編碼方式,他很好的解決了複雜檔案在傳輸中的問題,也因此被廣泛的應用在各種場景之中。關於 base64 的使用,你還需要知道如下幾點:

  1. base64 轉碼後的長度會有所變化,會比源資料的長度多出大約 1/3
  2. base64 不具有加密特性,因此他不適用於加密的場景
  3. 由於 base64 字元中會有 +,/ 等字元,因此如果需要 url 傳參的時候注意需要使用 URL 編碼一下,否則有可能會導致接受到的資料無法正常解密的情況

References

維基百科
Why do we use Base64?
What is base 64 encoding used for?