一、base64编码
Base64,是由小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"一共64个字符的组成的字符集,另外=可能作用右侧填充字符。
1、编码
StdEncoding:RFC 4648定义的标准base64编码字符集,结果填充=,使字节数为4的倍数。
URLEncoding:RFC 4648定义的另一base64编码字符集,用'-'和'_'替换了'+'和'/',用于URL和文件名,结果填充=。
RawStdEncoding:同 StdEncoding,但结果不填充=。
RawURLEncoding:同 URLEncoding,但结果不填充=。
package main
import (
"encoding/base64"
"fmt"
)
func main() {
input := "=小信1n!"
fmt.Println("input:", input)
e := base64.StdEncoding.EncodeToString([]byte(input))
fmt.Println("StdEncoding:", e, url.QueryEscape(e))
// StdEncoding: PeWwj+S/oTFuIQ== PeWwj%2BS%2FoTFuIQ%3D%3D
e = base64.URLEncoding.EncodeToString([]byte(input))
fmt.Println("URLEncoding:", e, url.QueryEscape(e))
// URLEncoding: PeWwj-S_oTFuIQ== PeWwj-S_oTFuIQ%3D%3D
e = base64.RawStdEncoding.EncodeToString([]byte(input))
fmt.Println("RawStdEncoding:", e, url.QueryEscape(e))
// RawStdEncoding: PeWwj+S/oTFuIQ PeWwj%2BS%2FoTFuIQ
e = base64.RawURLEncoding.EncodeToString([]byte(input))
fmt.Println("RawURLEncoding:", e, url.QueryEscape(e))
// RawURLEncoding: PeWwj-S_oTFuIQ PeWwj-S_oTFuIQ
}
2、混合解码
StdEncoding 和 RawStdEncoding 中存在+号,不应作为 query 参数传递,应采用 URLEncoding 或 RawURLEncoding 编码,或 首先对 query 参数进行 urlencord(将+号替换为%2B),然后再传递。
原因:query中,空格号会被编码为+,因此后端会将+号解码为空格(解码是底层框架自动完成的)。
func testBase64Decode() {
e := "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu+mZoiI="
e = "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu+mZoiI"
e = "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu-mZoiI="
e = "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu-mZoiI"
e = "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu mZoiI"
e = "dGl0bGU9IuWPsOW3niIgJiYgdGl0bGU9IuWMu mZoiI="
e = "PeWwj+S/oTFuIQ=="
e = "PeWwj+S/oTFuIQ"
e = "PeWwj-S_oTFuIQ=="
e = "PeWwj-S_oTFuIQ"
e = "PeWwj S/oTFuIQ=="
e = "PeWwj S/oTFuIQ"
//先替换空格为+
e = strings.ReplaceAll(e, " ", "+")
fmt.Println("ReplaceAll e:", e)
//再替换-为+号
e = strings.ReplaceAll(e, "-", "+")
fmt.Println("ReplaceAll e:", e)
//再替换_为/号
e = strings.ReplaceAll(e, "_", "/")
fmt.Println("ReplaceAll e:", e)
//填充=,字节为4的倍数
for len(e)%4 != 0 {
e += "="
}
fmt.Println("填充=后, e:", e)
//再base64非标准解码
d, err := base64.StdEncoding.DecodeString(e)
if err == nil {
fmt.Println("output:", string(d))
return
}
fmt.Println("err:", err)
}