base64 编码
base64
编码是使用 64 个可打印 ASCII
字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成 ASCII
字符串,另有 “=” 符号用作后缀用途。
base64
是网络上最常见的用于传输 8Bit 字节码的编码方式之一,base64
就是一种基于 64 个可打印字符来表示二进制数据的方法。
base64
编码是从二进制到字符的过程,可用于在 HTTP
环境下传递较长的标识信息。采用 base64
编码具有不可读性,需要解码后才能阅读。
数值 | 字符 | 数值 | 字符 | 数值 | 字符 | 数值 | 字符 | |||
---|---|---|---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w | |||
1 | B | 17 | R | 33 | h | 49 | x | |||
2 | C | 18 | S | 34 | i | 50 | y | |||
3 | D | 19 | T | 35 | j | 51 | z | |||
4 | E | 20 | U | 36 | k | 52 | 0 | |||
5 | F | 21 | V | 37 | l | 53 | 1 | |||
6 | G | 22 | W | 38 | m | 54 | 2 | |||
7 | H | 23 | X | 39 | n | 55 | 3 | |||
8 | I | 24 | Y | 40 | o | 56 | 4 | |||
9 | J | 25 | Z | 41 | p | 57 | 5 | |||
10 | K | 26 | a | 42 | q | 58 | 6 | |||
11 | L | 27 | b | 43 | r | 59 | 7 | |||
12 | M | 28 | c | 44 | s | 60 | 8 | |||
13 | N | 29 | d | 45 | t | 61 | 9 | |||
14 | O | 30 | e | 46 | u | 62 | + | |||
15 | P | 31 | f | 47 | v | 63 | / |
base64
将输入字符串按字节切分,取得每个字节对应的二进制值(若不足 8 比特则高位补 0),然后将这些二进制数值串联起来,再按照 6 比特一组进行切分,最后一组若不足 6 比特则末尾补 0。将每组二进制值转换成十进制,然后在上述表格中找到对应的符号并串联起来就是 base64
编码结果。
由于二进制数据是按照 8 比特一组进行传输,因此 base64
按照 6 比特一组切分的二进制数据必须是 24 比特的倍数(6和8的最小公倍数)。24 比特就是 3 个字节,若原字节序列数据长度不是 3 的倍数时且剩下 1 个输入数据,则在编码结果后加 2 个 =;若剩下 2 个输入数据,则在编码结果后加 1 个 =。
完整的 base64
定义可见 RFC1421
和 RFC2045
。因为 base64
算法是将 3 个字节原数据编码为 4 个字节新数据,所以 base64
编码后的数据比原始数据略长,为原来的 4/3。在电子邮件中,根据 RFC822
规定,每 76 个字符,还需要加上一个回车换行。可以估算编码后数据长度大约为原长的 135.1%。
base64
可用于任意数据的底层二进制数据编码,以应用于只能传输 ASCII
字符的场合。不过最常用于文本数据的处理传输,例如在 MIME
格式的电子邮件中,base64
可以用来编码邮件内容,方便在不同语言计算机间传输而不乱码,注意是传输而不是显示,例如在西欧地区计算机上使用 UTF-8
编码即可正常显示中文(安装有对应字库),但是它未必能正常传输中文,这时转换为 base64
便无此顾虑。
base64
编码若无特别说明,通常约定非 ASCII
字符按照 UTF-8
字符集进行编码处理。
golang
中 base64
的编码和解码可以用内置库 encoding/base64。
base64 编码示例:
package main import ( "encoding/base64" "fmt" "log" ) func main() { input := []byte("hello world") fmt.Println("原始内容:" + string(input)) // 演示base64编码 encodeString := base64.StdEncoding.EncodeToString(input) fmt.Println("编码:" + encodeString) // 对上面的编码结果进行base64解码 decodeBytes, err := base64.StdEncoding.DecodeString(encodeString) if err != nil { log.Fatalln(err) } fmt.Println("解码:" + string(decodeBytes)) // 如果要用在url中,需要使用 URLEncoding uEnc := base64.URLEncoding.EncodeToString([]byte(input)) fmt.Println("url编码:" + uEnc) uDec, err := base64.URLEncoding.DecodeString(uEnc) if err != nil { log.Fatalln(err) } fmt.Println("url解码:" + string(uDec)) }
运行结果如下:
原始内容:hello world 编码:aGVsbG8gd29ybGQ= 解码:hello world url编码:aGVsbG8gd29ybGQ= url解码:hello world