什么是Base64编码
Base64是一种二进制到文本的编码方案。它通过将其转换为基数-64表示形式,以可打印的ASCII字符串格式表示二进制数据。此类系统的一个例子是电子邮件 (SMTP),它传统上设计用于处理 7 位 US-ASCII 字符集中的纯文本数据。虽然,它后来扩展到支持非US-ASCII文本消息以及音频和图像等非文本消息,但仍建议将数据编码为ASCII字符集以实现向后兼容性。当需要通过无法正确处理二进制数据的媒体传输二进制数据时,通常使用 Base64 编码,并且旨在处理仅属于 7 位 US-ASCII 字符集的文本数据。
Base64 编码将任何二进制数据或非 ASCII 文本数据编码为可打印的 ASCII 格式,以便可以通过任何通信通道安全地传输。例如,当您向朋友发送包含图像的电子邮件时,您的电子邮件软件 Base64 会对图像进行编码,并在邮件中插入等效文本,如下所示 -
Content-Disposition: inline;
filename=favicon-16x16.png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAARdQTFRFAAAAAAAAAAAAAAAAAQEBDAwMHBwcHx8fCwsLAwMDGRkZHh4eBAQEICAgtra2vb29pKSksLCwODg4FBQUh4eHtLS0m5ubISEh3NzciIiIERERwsLCnp6eAgICjIyMwMDAJycnDg4OBQUFEBAQ0NDQe3t7ycnJeXl5KCgo3d3daWlpCQkJDw8PzMzMmpqarKysyMjIOjo6kZGR9/f3sbGxnZ2dPDw8z8/Pfn5+FxcXjo6OsrKybm5u5ubmExMTBgYG1NTUiYmJCgoKTk5O39/fbGxs7OzsVFRUGhoa2tra9PT00dHRMTExzs7OhoaGhYWFLCwsIyMjuLi4xcXFUlJSRUVFvr6+2dnZoaGhFhYWBwcHFRUV////p5PkYgAAAAN0Uk5Tnvn4e+Nx/gAAAAFiS0dEXOrYAJcAAAAJcEhZcwAAAEgAAABIAEbJaz4AAACnSURBVBjTY2BgZEYCjAwMTMwogImBGQ0ABVhY2dg5gExOLm4esAAvH7+AoBCzsIiomDhYgEtCUkpaRlZOXkFRCSygrKIqrqauoamlqA0xQ0dXT9/A0MjYxNQMIqBsbmFpZW1ja2hnDxGwc3B0cnZxdXNnZmEBC3h4esmJefv4uvj5B4AFAoP0zINDmEPDwiMiwQJR0UrROkDFHNFREDPQnI7hOXTvAwCtbBUc7QjTawAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0wMS0yMFQwNjo1NTozNiswMDowMA0Ih5IAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDEtMjBUMDY6NTU6MzYrMDA6MDB8VT8uAAAARnRFWHRzb2Z0d2FyZQBJbWFnZU1hZ2ljayA2LjcuOC05IDIwMTQtMDUtMTIgUTE2IGh0dHA6Ly93d3cuaW1hZ2VtYWdpY2sub3Jn3IbtAAAAABh0RVh0VGh1bWI6OkRvY3VtZW50OjpQYWdlcwAxp/+7LwAAABh0RVh0VGh1bWI6OkltYWdlOjpoZWlnaHQAMTkyDwByhQAAABd0RVh0VGh1bWI6OkltYWdlOjpXaWR0aAAxOTLTrCEIAAAAGXRFWHRUaHVtYjo6TWltZXR5cGUAaW1hZ2UvcG5nP7JWTgAAABd0RVh0VGh1bWI6Ok1UaW1lADE1NDc5NjczMzaP/6esAAAAD3RFWHRUaHVtYjo6U2l6ZQAwQkKUoj7sAAAAVnRFWHRUaHVtYjo6VVJJAGZpbGU6Ly8vbW50bG9nL2Zhdmljb25zLzIwMTktMDEtMjAvMTVjOGNmYTk5NjBmYmJjOWUyY2NjNGI4MTY2YTI3NTQuaWNvLnBuZ0jyrXwAAAAASUVORK5CYII=
Base64编码如何工作?
RFC 4648 中描述了 Base64 编码。Base64 编码适用于 US-ASCII 字符集的 65 个字符子集。65 个字符子集中的前 64 个字符映射到等效的 6 位二进制序列 ()。额外的第 65 个字符 () 用于填充。26 = 64=
从 0 到 63 的每个 6 位二进制序列都分配有一个 Base64 字母表。在编码过程中使用 6 位二进制序列和相应的 Base64 字母表之间的这种映射。以下是映射表,也称为 Base64 索引或字母表 -
# The Base64 Alphabet |
Value Encoding Value Encoding Value Encoding Value Encoding |
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 (pad) = |
15 P 32 g 49 x |
16 Q 33 h 50 y |
当输入末尾少于 24 位时,添加零位(右侧)以形成 6 位组的整数。然后,根据以下情况输出一个或两个 pad () 字符 -=Base64 编码算法接收 8 位字节的输入流。它从左到右处理输入,并通过连接三个 8 位字节将输入组织成 24 位组。然后将这些 24 位组视为 4 个串联的 6 位组。最后,通过查阅上面的 Base64 字母表,将每个 6 位组转换为 Base64 字母表中的单个字符。
- 最后一个输入块正好包含 8 位:添加四个零位以形成两个 6 位组。每个 6 位组都使用 Base64 索引表转换为生成的 Base64 编码字符。之后,两个填充 () 字符将附加到输出中。=
- 最后一个输入块正好包含 16 位:添加两个零位以形成三个 6 位组。三个 6 位组中的每一个都转换为相应的 Base64 字母表。最后,在输出后附加一个键盘()字符。=
输入:ab@yz
二进制表示(8 位序列):
1100001 01100010 01000000 01111001 01111010
第 1 步:将输入组织到 24 位组中(每个组有四个 6 位组)。末端用零位填充,形成 6 位组的整数号。
011000 010110 001001 000000 011110 010111 101000 # (padded with two zeros at the end)
第 2 步:通过将 Base64 索引表的索引将 6 位序列转换为 Base64 字母。如果在输入末尾添加零位,则添加填充字符。
上述 6 位组等同于以下索引:
24 22 9 0 30 23 40
索引到 Base64 字母表中会给出以下输出:
使用 URL 和文件名安全字母进行 Base64 编码YWJAeXo= # (padded with `=` to account for extra bits added)
RFC 4648 描述了一种 Base64 编码变体,它是 URL 和文件名安全的。这意味着,此 Base64 编码变体生成的输出可以在 URL 中安全地传输并在文件名中使用。
此变体对 Base64 字母表进行了简单的更改。由于字符在 URL 和文件名中具有特殊含义,它们被替换为连字符 () 和下划线 (+/-_)
# The "URL and Filename safe" Base 64 Alphabet | |||||
Value Encoding Value Encoding Value Encoding Value Encoding | |||||
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 - (hyphen) | |||||
12 M 29 d 46 u 63 _ (underscore) | |||||
13 N 30 e 47 v | |||||
14 O 31 f 48 w (pad) = | |||||
15 P 32 g 49 x | |||||
16 Q 33 h 50 y |
Base64编码用法
Base64 最常用于对二进制数据(例如,图像或声音文件)进行编码,以便嵌入到 HTML、CSS、EML 和其他文本文档中。此外,Base64 还用于对在传输、存储或输出过程中可能不受支持或损坏的数据进行编码。以下是该算法的一些应用:- 发送电子邮件时附加文件
- 通过数据 URI 在 HTML 或 CSS 中嵌入图像
- 保留加密函数的原始字节数
- 在 API 响应中将二进制数据输出为 XML 或 JSON
- 当 BLOB 不可用时将二进制文件保存到数据库
- 隐藏秘密不被窥探(真的是一个非常糟糕的主意)
Base64编码历史
Base64的历史很久以前就开始了,当时工程师们争论一个字节应该有多少位。现在我们使用八位字节,但在此之前使用的是七位、六位甚至三位字节。当八位编码被批准为标准时,许多系统使用旧的编码,不支持“新标准”。这导致在新旧系统之间的传输过程中丢失了一些数据。例如,邮件服务器在发送电子邮件时可能会丢弃第八位。此外,邮件服务器还有另一个问题——它们只能发送文本,而不能发送二进制数据(如图像、视频、档案)。因此,以一种神奇的方式,聪明的头脑开发了一种算法来解决这些问题。当然,随着时间的推移,开发了其他二进制到文本编码,但由于简单性、效率和便携性,Base64 成为最受欢迎的,几乎无处不在。早在 1987 年,一份描述PEM协议的文档首次描述了该算法(如果您对详细信息感兴趣,请查看 RFC 989 § 4.3)。从那时起,该算法不断发展,产生了在整个IT世界中积极使用的新标准。