作者:林冠宏 / 指尖下的幽靈
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 東西:
一個字符所對應表格中的下標的 bit 位是多少個
- 對應的
編碼表格
是多少
上述兩點是什么意思呢?
首先我們知道數據類型 char
一般占2個字節,當然還有二般的情況,比如1個字節,但這里我們以2字節為例,例如: char r = 'a'
,那么如果這種規則被修改了呢,既然可以使用2個字節表示一個字符,那么為什么不可以用3字節,5字節表示?當我們其它的字節個數表示一個字符的時候,就會產生其它效果。而,上述的第一點就是類似這個意思。當代表下標的 bit 位的個數變了,下標的取值范圍也跟着變,比如 2 個 bit 位最大的數是 11
= 3,而 3 個 bit 位最大的數是 111
= 7 。
對於第二點來說,就是一個用來供查表的表格,例如9x9乘法表
。這個表格是要被查詢的。
編碼流程
當有了上述兩點的條件后,我們將編碼的流程
總結為下面幾點:
例如要被編碼的字符串是:ILU
-
將
ILU
字符串中的每個字符轉為對應於Ascii
編碼表的值,I = 73, L = 76, U = 85。 -
將第一步中的
Ascii
值分別轉為對應的二進制
格式,要求必須是形成8 個 bit
,不足8比特位高位補0。例如:1 的二進制是 1,明顯不夠8位,最終應該顯示為:0000 0001
。ILU
的轉化結果如下:73 = 01001001
76 = 01001100
85 = 01010101
-
根據
base X
(這里的 X 代表 16,32,64等編號) 編碼算法中所指定的y 個 bit 位為一個字符在表格中的下標
的規則,對第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的需要bit位個數和編碼表的總字符
名稱 | 下標數字的位個數 | 編碼表字符串 | 位數不足是否會補全 = |
---|---|---|---|
base 16 | 4 | 數字0~9 和 字母 A~F | 不會,位數剛好是 4 的倍數 |
base 32 | 5 | 大寫字母A~Z 和 數字2~7 | 會 |
base 64 | 6 | 大寫字母AZ,小寫字母az,數字0~9以及"+","/" | 會 |
名稱 | 編碼后,數據量變化 |
---|---|
base 16 | 由一個8位表示一個字符 變成 4位表示一個字符,數據量變 2 倍 |
base 32 | 變為 8/5 倍 |
base 64 | 變為 8/6=4/3 倍 |
補全的限制,拿base32 來說,因為每5位表示一個字符下標值,而原始數據是8位,這就意味着,划分會出現剩下的情況,例如:
8 - 5 = 3
,明顯有3個 bit 位剩下,那么至少要多少個位才能滿足步出現剩下的呢?這是一個最小公倍數問題,就是: 5*8 = 40 位。我們可以驗證一下,當兩個字符的時候,是16位,16/5 = 1,以此類推。
最終,得出在 base32 的編碼中,待編碼數據至少要 >= 40 位,其最終的編碼結果才能不出現 =
號。例如要被編碼的字符是3
,很明顯,它的結果是:D=======
,后面的 =
都是補全的。
同理,base64 的是至少 24 位,24 是 6 和 8 的最小公倍數。
上述,就是所有內容,記住此類編碼方式的主要點:
- 一個字符所對應表格中的下標的 bit 位是多少個
- 對應的編碼表格是多少
剩下的,就是照着模式走,划分、對表,得出結果。
廣告時間
我的由清華大學出版社出版的區塊鏈純技術書籍:
《區塊鏈以太坊DApp開發實戰》
現已出版並可網購。
適合區塊鏈初中級工程師閱讀。
