解讀Base64編碼中為什么會(huì)有等號(hào)(=)問(wèn)題
Base64編碼中為什么會(huì)有等號(hào)(=)
如果對(duì)字符串"ab"進(jìn)行Base64編碼,得到的結(jié)果將是:YWI=,結(jié)果中為什么會(huì)出現(xiàn)=呢,這就需要了解一下base64編碼背后的原理。
Base64是一種便于網(wǎng)絡(luò)傳輸?shù)淖止?jié)碼編碼方式,之所以叫Base64是由于它的編碼結(jié)果是由64個(gè)可打印字符組成,這些字符在不同系統(tǒng)間是通用的。
64個(gè)字符如下表所示
索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 | 索引 | 對(duì)應(yīng)字符 |
0 | A | 17 | R | 34 | i | 51 | z |
1 | B | 18 | S | 35 | j | 52 | 0 |
2 | C | 19 | T | 36 | k | 53 | 1 |
3 | D | 20 | U | 37 | l | 54 | 2 |
4 | E | 21 | V | 38 | m | 55 | 3 |
5 | F | 22 | W | 39 | n | 56 | 4 |
6 | G | 23 | X | 40 | o | 57 | 5 |
7 | H | 24 | Y | 41 | p | 58 | 6 |
8 | I | 25 | Z | 42 | q | 59 | 7 |
9 | J | 26 | a | 43 | r | 60 | 8 |
10 | K | 27 | b | 44 | s | 61 | 9 |
11 | L | 28 | c | 45 | t | 62 | + |
12 | M | 29 | d | 46 | u | 63 | / |
13 | N | 30 | e | 47 | v | ||
14 | O | 31 | f | 48 | w | ||
15 | P | 32 | g | 49 | x | ||
16 | Q | 33 | h | 50 | y |
大家可以看到這里面并沒(méi) '=' 這個(gè)字符,這是因?yàn)?’=‘ 其實(shí)是填充字符。
如果需要表示上面的64個(gè)字符,那么需要6bit,也就是2^6=64,base64的核心思想就是,將3個(gè)
字節(jié)拆分成4個(gè)6bit,然后對(duì)每個(gè)6bit的高位補(bǔ)2個(gè)0,構(gòu)成1個(gè)字節(jié)。也即是每3個(gè)字節(jié)最終結(jié)果將變成4個(gè)字節(jié)。
如果原始字符串的字節(jié)數(shù)不是3的整數(shù)倍,那么就用0來(lái)填充,用來(lái)填充的0就被編碼成了'=',這就是出現(xiàn)=的原因,并且只會(huì)出現(xiàn)在結(jié)果出,如果原始字符剛好是3字節(jié)的整數(shù)倍,那么就沒(méi)有等號(hào)了。
回到開頭的例子,我們看下ab是如何計(jì)算得到Y(jié)WI=的。
- 1、ab對(duì)應(yīng)的ascaii編碼的二進(jìn)制表示為:011000001 01100010
- 2、由于只有兩個(gè)字節(jié),需要填充到3個(gè)字段,也就是:011000001 01100010 00000000
- 3、拆分成四個(gè)6bit:011000 010110 001000 000000
- 4、高位補(bǔ)兩個(gè)0,變成四字節(jié):00011000 00010110 00001000 00000000
- 5、按照上表的對(duì)應(yīng)關(guān)系:24-Y 22-W 8-I 填充-=, 也即是YWI=。
需要注意填充的0是要被轉(zhuǎn)化成=,而不是上表中的A。
順便附上golang示例代碼
func main() { str := "ab" // base64編碼 encodedStr := base64.URLEncoding.EncodeToString([]byte(str)) fmt.Println(encodedStr) // YWI= // base64解碼 decodeStr, _ := base64.URLEncoding.DecodeString(encodedStr) fmt.Println(string(decodeStr)) // ab }
如果不希望保留填充的=,可以在編碼后去掉,解碼前填充上
示例代碼如下:
func main(){ str := "ab" // base64編碼 encodedStr := base64.URLEncoding.EncodeToString([]byte(str)) encodedStr = strings.TrimRight(encodedStr, "=") // 去掉填充的= fmt.Println(encodedStr) // YWI // 解碼時(shí),長(zhǎng)度不是4的倍數(shù),需要用=填充 i := len(encodedStr) % 4 if i != 0 { encodedStr += strings.Repeat("=", 4-i) } // base64解碼 decodeStr, _ := base64.URLEncoding.DecodeString(encodedStr) fmt.Println(string(decodeStr)) // ab }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
hadoop遷移數(shù)據(jù)應(yīng)用實(shí)例詳解
這篇文章主要介紹了hadoop遷移數(shù)據(jù)應(yīng)用實(shí)例,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06chatgpt成功解決Access denied 1020錯(cuò)誤問(wèn)題(最新推薦)
從前兩天網(wǎng)上開始一直開著的chatgpt網(wǎng)頁(yè)突然打不開了,提示1020錯(cuò)誤,嘗試換了不同代理軟件或者代理地點(diǎn)仍然無(wú)法解決,這篇文章主要介紹了chatgpt成功解決Access denied 1020錯(cuò)誤,需要的朋友可以參考下2023-05-05聊聊Flare應(yīng)用前后端性能優(yōu)化問(wèn)題
這篇文章主要介紹了Flare應(yīng)用前后端性能優(yōu)化,制作?flare?的過(guò)程,其實(shí)也是?flame?性能調(diào)優(yōu)的過(guò)程。不過(guò)在解決問(wèn)題之前,我們首先得能定位問(wèn)題有哪些,帶著這些問(wèn)題一起通過(guò)本文學(xué)習(xí)吧2022-02-02國(guó)外開發(fā)者談為何放棄PHP而改用Python
本文作者作為一名從事PHP開發(fā)11年的資深開發(fā)者,卻放棄了PHP而改用Python。2009-09-09thymeleaf實(shí)現(xiàn)th:each雙重多重嵌套功能
今天給大家分享一個(gè)使用 thymeleaf 實(shí)現(xiàn)一個(gè)動(dòng)態(tài)加載一二級(jí)文章分類的功能,本文通過(guò)代碼講解的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-11-11