Base64 编码
Base64 编码,顾名思义,是基于 64 个字符进行编码。规则如下:
- Base64 字符集(以标准 Base64 为例, 26 大写, 26 小写, 10 数字,以及+、/)为 ABC...YZabc...yz012...89+/;
- 每 6bit 为一组(2^6=64),即 每 3 个字节为 4 组 ;
- 每组映射为一个 Base64 字符;
如果要编码的二进制数据不是 3 的倍数,最后会剩下 1 个或 2 个字节怎么办?**标准编码(StdEncoding)**会先在末尾用 0x00 补齐再分组,并将最后 2 个或 1 个 6bit 分组(全为 0 填充)映射为'=',表示补齐的 0 字节数量。
举个例子,以 0x12 34 ab cd 编码为标准 base64 为例:
- 不足 3 的倍数,先用两个 0 字节补齐 -->0x12 34 ab cd 00 00
- 0x12 34 ab 编码为 EjSr
- 0xcd 00 00 二进制为 0b1100 1101 0000 0000 0000 0000,分为 4 组后为 110011 010000 000000 000000,编码结果为 zQ==
- 最终编码结果为 EjSrzQ==
解码过程注意末尾字节的处理即可,此处不再赘述。
- EjSrzQ==-->0x12 34 ab cd 00 00-->0x12 34 ab cd
标准编码中编码结果字符长度一定是 4 的倍数,且是原始数据字节数的 4/3 倍 ,因为会将字节数据补齐至 3 的倍数,每 3 个字节编码为 4 个字符。 在 ASCII 或 UTF-8 编码下,存储结果字符串需要的空间是原始数据的 4/3 倍,存储效率为 75% 。
根据字符集的不同,Base64 编码有几个变种,除了标准编码(StdEncoding),常见的还有 URL 编码(URLEncoding)、原始标准编码(RawStdEncoding)以及原始 URL 编码(RawUrlEncoded)。
简单来说,Raw 指的是无 Padding,URL 指的是用-和_取代编码结果中包含的 url 关键字+和/。不妨参考 Golang 中 encoding/base64 包中的描述:
// StdEncoding is the standard base64 encoding, as defined in
// RFC 4648.
var StdEncoding = NewEncoding(*encodeStd*)
// URLEncoding is the alternate base64 encoding defined in RFC 4648.
// It is typically used in URLs and file names.
var URLEncoding = NewEncoding(*encodeURL*)
// RawStdEncoding is the standard raw, unpadded base64 encoding,
// as defined in RFC 4648 section 3.2.
// This is the same as StdEncoding but omits padding characters.
var RawStdEncoding = StdEncoding.WithPadding(*NoPadding*)
// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
// It is typically used in URLs and file names.
// This is the same as URLEncoding but omits padding characters.
var RawURLEncoding = URLEncoding.WithPadding(*NoPadding*)
与标准编码不同的是, 原始编码中,字节数不足 3 的倍数时不会补齐字节数 ,采用如下方案:
- 如果剩余 1 字节,则左移 4bit 后转换为 2 字符;
- 如果剩余 2 字节,则左移 2bit 后转化为 3 字符;
即 原始编码方案中,结果字符串长度可以不是 4 的倍数 。
Hex 编码可以看成“Base16 编码”。随着字符数量的增加,存储效率也随之增加。如果有“Base256”编码,存储效率岂不就 100%了?很遗憾,主流字符编码中,单字节能表示的可打印字符只有 92 个。通过扩充多字节字符,或用组合字符实现 base256 意义不大。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论