Base64 編碼原來這麼簡單

做了六七年程序員,經常用到 Base64 編碼,但對於爲什麼要用,以及它的原理,一直是不求甚解。最近在某本書上看到了 Base64 的編碼原理,原來這麼這麼這麼簡單。

Base64 解決了什麼問題

假如我們要在網絡中傳輸下面的問題

你好  小朋友

我是磚家

你是誰?

這段文本中包含了空格、換行、回車等不可見字符,在網絡傳輸中,各個設備對不可見字符處理機制可能不同,會存在信息傳輸錯誤的情況。此時我們就需要一種編碼機制,把不可見字符統統轉成可見字符。

Base64 編碼原理

接下來我們通過將 abcd二字轉爲 Base64 編碼,來了解下它的原理。

  1. 把字符三三分組,不夠時通過 0 補齊。比如 abc三個字符歸一組,d 不夠三位,通過 0 補齊爲 d00

  1. 把字符轉換成二進制 ASCII 編碼

  1. 把轉換後的二進制,每六位分隔開

Q:爲什麼第一步需要分三個字符一組?

A:因爲 ASCII 碼每個字符是 8 位二進制,3 * _8 = 24。正好可以被第三步拆分爲 4 個 6 位二進制,4 * _6 = 24。

  1. 6 位二進制能代表 0-63,我們有一個彩虹表,可以將 0-63 分別對應一個字符,彩虹表如下:

通過彩虹表,我們可以將每 6 位分割後的二進制做一次轉換

需要注意的是,凡是補位產生的 0,需要用 = 來表示。所以最後的兩位都是 =

最後 abcd 轉換爲 Base64 編碼後爲 YWJjZA==,整體原理還是比較簡單的,不涉及到高深的算法。

Base64 周邊

  1. 由於 Base64 轉碼後會包含 +/=字符,在 URL 不能正常傳輸。所以有一種 URL 友好型的 Base64 編碼,它存在使用 _-來代替 +/,並且不在末尾追加 =

  2. Base32、Base16 的原理和 Base64 基本一致

  3. Base64 並不適合加密,因爲解密太簡單了

  4. 漢字通過 gb2312utf-8gbk編碼後,即可轉成二進制處理。這裏借用網上的一個圖片說明:

Base58 與 Base58Check

Base58 是比特幣在生成錢包地址時使用的一種編碼形式。它和 Base64 的主要區別是去掉了肉眼容易看錯的字符 0(零)、O(大寫字母 O)、I(大寫字母 i)、l(小寫字母 L)和幾個影響雙擊選擇的字符:/ 和 + 這種編碼的目的比較簡單,就是防止在轉賬時,看錯賬號,轉錯賬。Base58 的原理更簡單一些,只涉及到進制的轉換,大致步驟如下:

  1. 將字符轉成 ASCII 碼

  2. 將 ASCII 碼轉換成 58 進制

  3. 通過彩虹表映射即可

比如 abcd轉換:

  1. 轉成 ASCII 碼 97-98-99-100

  2. 轉換成 58 進制 3-28-21-49-5-22

  3. 通過如下彩虹表映射爲 3VNr6P

Base58Check 編碼,顧名思義是可以對 Base58 編碼進行檢查。比如我在傳輸 qH912cvztx編碼時,如果網絡異常等各種原因,導致數據錯亂或丟失,接收方要能夠識別出來數據有問題。Base58Check 編碼基本原理如下:

  1. 在 data 前面添加一個版本標識 prefix,用來識別編碼的數據類型,比如比特幣地址的前綴是 0(十六進制是 0x00)

  2. 通過 hash 算法計算 prefix + data的 hash 值:SHA256(prefix + data)

  3. 將生成的 hash 值截斷爲前四位,拼接到後面 prefix + data + 4 位 hash

  4. 將上一步生成的結果進行 Base58 編碼計算,得到最終結果

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/RKi-TH57IUCCfxugHgkp8g