[每日短篇] E - Base64 编码
2019獨角獸企業重金招聘Python工程師標準>>>
首先,Base64 是一種編碼方式而非一種加密方式,Base64 可以僅憑編碼后的文本還原出未編碼的文本,不需要任何額外信息。在有的系統中,定義的可接受的字符范圍有限,但是用戶又期望存儲任意數據,早期一個典型的應用是在郵件中發送多媒體內容,另外一個則是在 7 位字符系統中存儲 8 位二進制數據。
在計算機中存儲的所有數據都是以數值的形式存儲的,在某種意義上可以理解為系統是以 256 進制表示數據的(注意是表示不是存儲)。256 進制數有 256 個數字,通常會用 ascii8 編碼表中的字符表示,但是其中有超過一半的字符人類沒有給它設定一個通用、固定且肉眼容易識別的圖案。Base64 則是將 256 進制表示的數值改為用 64 進制存儲,這樣只需要有 64 個不同的圖案就可以表示一個數值,在 Base64 中選擇的是 A-Za-z0-9+/ 這 64 個字符,其中 A 在十進制中是 0,/ 在十進制中是 63。
選擇 64 進制在轉換數據時可以更方便操作,就像 2、8、16 進制之間相互轉換非常簡單一樣,2 的冪次進制間相互轉換都相對容易,最容易的方式是冪次有倍數關系的進制間轉換,比如 2 和 8、2 和 16,高冪次的 1 位規整地對應低冪次的 n 位不需要進位或借位。例如
2 = 2^1 8 = 2^3 8 進制數值中 1 位數字可以直接轉換成 3 位 2 進制數字,或者反過來將 2 進制數值從最低位每 3 位一組劃分就可以對應轉換為 8 進制數值。對于冪次沒有倍數關系的,在編程轉換時也沒有任何困難,因為位操作是針對 2 進制的操作,而任何自然數都是 1 的倍數。因為存在這種關系,所以首先基數會選擇 2 的冪次,之后的問題就是在冪次中選擇幾的問題。往值增大的方向看,取值越大需要的可打印字符越多,而實際上我們僅有不到 127 個 (ascii7) 可選的值。往值減小的方向看,不要忘記每個數字最終還需要 8 位 1 個字節來存儲,這就帶來了存儲膨脹的問題,假設冪次選擇 1,可以僅用 0/1 這 2 個字符來表示,那么 1 個字節就要變為 8 個,變為 8 倍。通常來說,從 2^m 進制轉換為 2^n 進制(m,n <= 8),其空間占用會變為原來的 m/n。對 Base64 來說就是 4/3,增加 33% 左右,在實際中 Base64 不是簡單的進制轉換,還有另外一些規則,所以實際增加大小還略多于 33%。如果用 32 作為基數,則會至少增加 60%。所以綜合看來,選擇 64 進制還是一個比較平衡的選擇。
Base64 的主要算法就是把要編碼的文本從左往右(注意我們討論進制轉換時通常認為低位在右邊,但是這僅僅是人類的習慣而已)每 3 字節一組轉換成 4 位 Base64 數字。代碼可以很開心地從開頭一直做轉換,直到最后可能遇到末尾一組是 1 個或者 2 個字符,這時候不能簡單地增加 pad 字符湊齊 3 個字符,因為轉換的內容可能是二進制內容,任意字符都是有意義的。在 Base64 中的處理是最后不滿 6 位的部分補0,然后在編碼結果后面添加若干 = 湊夠 4 位 Base64 數字。如果最后一組只有 1 個字符,則補 4 位 2 進制 0,也就是湊夠 12 位可以轉換成 2 位 Base64 數字,然后在編碼結果后面增加 2 個 = 字符湊夠一組 4 位 Base64 數字。如果最后一組有 2 個字符,則補 2 位 2 進制 0,也就是湊夠 18 位可以轉換成 3 位 Base64 數字,然后在編碼結果后面增加 1 個 = 字符湊夠一組 4 位 Base64 數字。也就是像下面這樣
+--------+-------------------------------+-------------------------------+-------------------------------+ | char | A | | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | bin | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | | | | | | | | | | | | | | | | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | pad | | | | | | | | | 0 | 0 | 0 | 0 | | | | | | | | | | | | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | Base64 | Q | Q | = | = | +--------+-----------------------+-----------------------+-----------------------+-----------------------++--------+-------------------------------+-------------------------------+-------------------------------+ | char | B | C | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | bin | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | | | | | | | | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | pad | | | | | | | | | | | | | | | | | 0 | 0 | | | | | | | +--------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | Base64 | Q | k | M | = | +--------+-----------------------+-----------------------+-----------------------+-----------------------+自此,Base64 的主要算法就講完了。最后需要注意一點,Base64 是一種編碼方式的名稱,而不是一類編碼方式的名稱,還有一些以 64 為基數的編碼方式,它們要么有別的名字要么屬于 Base64 的變種,但是要跟 Base64 這種編碼方式區分開。
轉載于:https://my.oschina.net/u/1762727/blog/2876370
總結
以上是生活随笔為你收集整理的[每日短篇] E - Base64 编码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解析JavaScript中的字符串类型与
- 下一篇: Dubbo基础介绍