做者:林冠宏 / 指尖下的幽靈html
GitHub : https://github.com/af913337456/程序員
騰訊雲專欄: https://cloud.tencent.com/developer/user/1148436/activitiesgithub
蟲洞區塊鏈專欄:https://www.chongdongshequ.com/article/1536563643883.html算法
PS: 本文目的,通俗簡短地介紹一次 base 類編碼方式,而後讓你記住。編碼
相信超過絕大多少的程序員都曾在各類的軟件開發中使用過編碼、解碼,編碼和解碼是對應的,有編碼就有解碼。加密
base16,base32,base64 都是編碼方式,對應有各自的一套編碼算法。code
可是有人常常稱它們是加密
,例如 base64 加密。其實這種說法不算全對。由於默認的
base16,base32,base64 的各類信息都是公開的,公開的包含有:htm
這個是主要
在 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 | 大寫字母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個 bit 位剩下,那麼至少要多少個位才能知足步出現剩下的呢?這是一個最小公倍數問題,就是: 5*8 = 40 位。咱們能夠驗證一下,當兩個字符的時候,是16位,16/5 = 1,以此類推。
最終,得出在 base32 的編碼中,待編碼數據至少要 >= 40 位,其最終的編碼結果才能不出現 =
號。例如要被編碼的字符是3
,很明顯,它的結果是:D=======
,後面的 =
都是補全的。
同理,base64 的是至少 24 位,24 是 6 和 8 的最小公倍數。
剩下的,就是照着模式走,劃分、對錶,得出結果。
個人由清華大學出版社出版的區塊鏈純技術書籍:
《區塊鏈以太坊DApp開發實戰》
現已出版並可網購。
適合區塊鏈初中級工程師閱讀。