作者:林冠巨集 / 指尖下的幽靈
GitHub : https://github.com/af913337456/
騰訊雲專欄: https://cloud.tencent.com/developer/user/1148436/activities
蟲洞區塊鏈專欄:https://www.chongdongshequ.com/article/1536563643883.html
PS: 本文目的,通俗簡短地介紹一次 base 類編碼方式,然後讓你記住。
目錄
- 前言
- 編碼流程
- 自定義表格
- 總結
前言
相信超過絕大多少的程式設計師都曾在各種的軟體開發中使用過編碼、解碼,編碼和解碼是對應的,有編碼就有解碼。
base16,base32,base64 都是編碼方式,對應有各自的一套編碼演算法。
但是有人經常稱它們是加密
,例如 base64 加密。其實這種說法不算全對。因為預設的
base16,base32,base64 的各種資訊都是公開的,公開的包含有:
- 演算法的運算方式
- 編碼表格,
這個是主要
在 base16,base32,base64 中,一旦掌握了上面兩類資訊,那麼就相當於破解了。甚至可以手動用筆寫出編碼後的結果以及根據編碼結果寫出解碼內容。
16,32和64它們編碼原理
都是一樣的,不同的地方在於下面 2 東西:
表示一個位元組的 byte 位是多少
- 對應的
編碼表格
是多少
上述兩點是什麼意思呢?
首先我們知道資料型別 char
一般佔2個位元組,當然還有二般的情況,但這裡我們以2位元組為例,例如: char r = 'a'
,那麼如果這種規則被修改了呢,既然可以使用2個位元組表示一個字元,那麼為什麼不可以用3位元組,5位元組表示?當我們其它的位元組個數表示一個字元的時候,就會產生其它效果。而,上述的第一點就是這個意思。
對於第二點來說,就是一個用來供查表的表格,例如9x9乘法表
。這個表格是要被查詢的。
編碼流程
當有了上述兩點的條件後,我們將編碼的流程
總結為下面幾點:
例如要被編碼的字串是:ILU
- 將
ILU
字串中的每個字元轉為對應於Ascii
編碼表的值,I = 73, L = 76, U = 85。 將第一步中的
Ascii
值分別轉為對應的二進位制
格式,要求必須是形成8 個 byte
,不足8位元位高位補0。例如:1 的二進位制是 1,明顯不夠8位,最終應該顯示為:0000 0001
。ILU
的轉化結果如下:73 = 01001001
76 = 01001100
85 = 01010101
根據
base X
(這裡的 X 代表 16,32,64等編號) 編碼演算法中所指定的y 個 byte 為一個位元組
的規則,對第2步的進行劃分。例如base 16
的規則要求,4位為一個位元組,每4個位為一部分,故劃分如下:第1部分:0100 是 (73 = 01001001,的前4個位)
第2部分:1001 是 (73 = 01001001,的後4個位)
第3部分:0100
第4部分:1100
第5部分:0101
第6部分:0101
將第三步中劃分出的
每個部分
進行10進位制轉換
,得出對應的10進位制數,如下:0100 = 4,1001 = 9,4,12,5,5
最後一步,將第4步中得出的數去
查表
,得出對應的字元,連在一起,就是編碼結果
base16 的預設編碼表字串是:
數字0~9
和字母A~F
,共16
個,將每個的下標和值列表格,如下所示:base16
的編碼表
| 下標 | 編碼值 | 下標 | 編碼值 |
| ------ | ------ | ------ | ------ |
| 0 | 0 | 8 | 8 |
| 1 | 1 | 9 | 9 |
| 2 | 2 | 10 | A |
| 3 | 3 | 11 | B |
| 4 | 4 | 12 | C |
| 5 | 5 | 13 | D |
| 6 | 6 | 14 | E |
| 7 | 7 | 15 | F |最終
ILU
的base16
編碼結果是:494C55
自定義表格
程式碼中,我們可以指定自己的編碼表
,例如下面的一行:
var encoding = base32.NewEncoding("ybndrfg8ejkmcpqxot1uwisza345h769")
ybndrfg8ejkmcpqxot1uwisza345h769
是 32 個字元,對應 base 32 編碼,下標 0
對應的字元是 y
當上面的 ILU
例子用 該表格編碼時,那麼就不再是: 494C55
總結
在上面的第3步,對於剛好能夠整數劃分的 (8 / 4 = 2 整除),是不會有出現在最終結果後面補充等於號"="符號
的情況的,而不能除盡的,將會被補充為 "=" 。下面是 16,32和64的需要位元組個數和編碼表的總字元
名稱 | 多少位為一位元組 | 編碼表字串 | 位數不足是否會補全 = |
---|---|---|---|
base 16 | 4 | 數字0~9 和 字母 A~F | 不會,位數剛好是 4 的倍數 |
base 32 | 5 | 大寫字母A~Z 和 數字2~7 | 會 |
base 64 | 6 | 大寫字母A~Z,小寫字母a~z,數字0~9以及"+","/" | 會 |
名稱 | 編碼後,資料量變化 |
---|---|
base 16 | 由一個8位表示一個字元 變成 4位表示一個字元,資料量變 2 倍 |
base 32 | 變為 8/5 倍 |
base 64 | 變為 8/6=4/3 倍 |
補全的限制,拿base32 來說,因為每5位表示一個位元組,而原始資料是8位,這就意味著,劃分會出現剩下的情況,例如:
8 - 5 = 3
,明顯有3個 byte 位剩下,那麼至少要多少個位才能滿足步出現剩下的呢?這是一個最小公倍數問題,就是: 5*8 = 40 位。我們可以驗證一下,當兩個字元的時候,是16位,16/5 = 1,以此類推。
最終,得出在 base32 的編碼中,待編碼資料至少要 >= 40 位,其最終的編碼結果才能不出現 =
號。例如要被編碼的字元是3
,很明顯,它的結果是:D=======
,後面的 =
都是補全的。
同理,base64 的是至少 24 位,24 是 6 和 8 的最小公倍數。
上述,就是所有內容,記住此類編碼方式的主要點:
- 表示一個位元組的 byte 位是多少
- 對應的編碼表格是多少
剩下的,就是照著模式走,劃分、對錶,得出結果。
廣告時間
我的由清華大學出版社出版的區塊鏈純技術書籍:
《區塊鏈以太坊DApp開發實戰》
現已出版並可網購。
適合區塊鏈初中級工程師閱讀。