如何生成 MIME Base64
- 把文本粘贴到 输入 · 文本。换行 已预设为 76 (MIME, LF)。
- 除非邮件声明了其他字符集,否则 字符集 保持为 UTF-8,并在
Content-Type头中使用相同的值。 - 从 输出 · Base64 复制换行后的 Base64,或按 下载 保存为
base64.txt。 - 对于证书或密钥正文,把 换行 切换为 64 (PEM)。对于 HTTP、JSON 或其他需要单行的场合,选择 不换行。
什么是 MIME Base64
MIME(RFC 2045)是让电子邮件能够携带附件、非英文文本和 HTML 的标准。当某个部分的正文是二进制或充满非 ASCII 字节时,发送方会把它编码为 Base64,并标记 Content-Transfer-Encoding: base64。在普通 Base64 的基础上,RFC 2045 增加了一条行长规则:编码后的每行最多 76 个字符。一行 76 个字符容纳 57 个输入字节。
这样编码的文本部分如下所示;两行 Base64 是本工具对下面引用的那句话的输出:
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
Q2Fmw6kgbWVudTogY3LDqG1lIGJyw7tsw6llLCBqYWxhcGXDsW8sIHNtw7ZyZ8Olc2JvcmQuIFRo
aXMgbGluZSBpcyBsb25nIGVub3VnaCB0byB3cmFwIGFmdGVyIDc2IGNoYXJhY3RlcnMu
原文是 Café menu: crème brûlée, jalapeño, smörgåsbord. This line is long enough to wrap after 76 characters.,UTF-8 下为 108 字节。用 Base64 解码器 把两行一起解码,就能还原这句话;换行会被忽略。
换行、CRLF 与大小
换行 提供两种 76 列的变体:76 (MIME, LF) 用换行符(\n)分隔各行,76 (MIME, CRLF) 使用 \r\n。线路上传输的电子邮件使用 CRLF,邮件库在序列化邮件时会转换行尾,所以在代码中用 LF 就可以。如果要把输出直接粘贴到原始 .eml 文件或 SMTP 会话中,请选择 CRLF 变体。
换行会在通常的 33% 之外再多占一点空间:
| 输出 | 每 57 个输入字节的字符数 | 额外开销 |
|---|---|---|
| 单行,不换行 | 76 | 33.3% |
| 76 字符一行,LF | 77 | 35.1% |
| 76 字符一行,CRLF | 78 | 36.8% |
邮件大小限制针对的是编码后的邮件,所以一个 10 MB 的附件大约要占用 13.7 MB 的额度。大小计算器 可以给出确切数字,电子邮件中的 Base64 解释了各部分如何组合在一起。
邮件头中的编码字
Subject、From 等邮件头不能使用 Content-Transfer-Encoding。邮件头中的非 ASCII 文本使用 RFC 2047 编码字:=?charset?B?base64?=。要生成一个编码字,把 换行 设为 不换行 来编码文本,再自己把结果包起来:
Subject: =?UTF-8?B?R3LDvMOfZSBhdXMgQmVybGlu?=
它解码为 Grüße aus Berlin。一个编码字最多 75 个字符;更长的主题会被拆成多个编码字,用空格分隔。对于以 ASCII 为主的文本,邮件软件通常改用 ?Q? 形式,它基于 quoted-printable。
在代码和命令行中使用 MIME Base64
Python 的 base64.encodebytes 用 \n 每 76 个字符换行,得到的行与本工具相同:
import base64
text = "Café menu: crème brûlée, jalapeño, smörgåsbord. This line is long enough to wrap after 76 characters."
print(base64.encodebytes(text.encode("utf-8")).decode("ascii"))
处理整封邮件时,email 包会替你处理编码、邮件头和 CRLF。在 Linux 上,GNU base64 默认每 76 个字符换行,openssl base64 每 64 个字符换行:
base64 attachment.pdf > attachment.b64
openssl base64 -in attachment.pdf -out attachment.pem.b64
如果要反过来拆解原始邮件,请在 电子邮件(EML)解码器 中打开,它会提取出正文和附件。
常见问题
为什么 MIME Base64 每行 76 个字符?
RFC 2045 把上限定为 76 个字符,远低于电子邮件 998 个字符的行长限制(RFC 5322)。76 是 4 的倍数,所以每行正好容纳 57 个字节。
MIME Base64 和普通 Base64 有区别吗?
字母表和填充完全相同。唯一的区别是换行,而解码器理应忽略换行,所以换行和不换行的版本解码出的字节相同。
邮件的 Subject 行中的 Base64 需要换行吗?
不需要。邮件头使用 RFC 2047 的编码字(encoded-word),例如 =?UTF-8?B?R3LDvMOfZQ==?=,其中不能包含换行。编码主题时把换行设为不换行,并让每个编码字不超过 75 个字符。
为什么 openssl 输出的是 64 字符一行?
openssl base64 按 PEM 惯例每 64 个字符换行,而 GNU base64 和大多数邮件库每 76 个字符换行。两者解码方式相同;如果需要与 openssl 完全一致的输出,在这里选 64。