Quoted-Printable

邮件正文 QP 编解码

423 次访问

Quoted-Printable 编码(RFC 2045)

输入0 字符
输出0 字符

关于 Quoted-Printable

· RFC 2045:MIME 标准的两种 Content-Transfer-Encoding 之一(另一种是 Base64)

· 设计目标:邮件正文里大部分是 ASCII 文本,仅少量非 ASCII 字符需转义 → 比 Base64 可读性高

· 编码规则
- ASCII 可打印字符(33-126,除 = 外)直接保留
- 其他字节 → =XX(XX 是大写十六进制)
- = 自身 → =3D
- 每行 ≤ 76 字符,超长用 =\n 软换行

· 常见场景:旧邮件客户端的 Content-Transfer-Encoding: quoted-printable 头部 / vCard / iCal

· vs Base64:英文为主的文本用 QP 更紧凑 + 可读 / 二进制内容用 Base64 更高效

关于本工具

了解工具定位 · 使用场景 · 对比优势

将邮件正文中的非ASCII字符、特殊符号或长行编码为可打印的QP格式,或还原为原始文本。需要处理邮件编码的开发人员、手动查看乱码邮件的用户、或编写邮件发送脚本时,直接粘贴文本即可编解码。所有操作在浏览器本地完成,内容不上传服务器。

使用场景

✉️

邮件乱码修复

收到一封包含特殊符号或非 ASCII 字符的邮件,正文乱码显示为 `=E4=B8=AD=E6=96=87` 等格式。将乱码内容粘贴到工具解码区,一键还原为原始中文或日文文本,无需手动对照编码表逐行转换,快速恢复邮件可读性。

🔧

邮件模板开发

开发 HTML 邮件模板时,图片或样式中的特殊字符(如 `©`、`™`)在部分邮件客户端中显示异常。使用工具对模板内容进行 QP 编码,确保所有非 ASCII 字符被安全转换为 `=C2=A9` 等格式,避免字符截断或乱码。

📡

旧系统数据迁移

从遗留的邮件系统或数据库导出用户信息时,字段中包含中文、俄语等字符,导出文件被 QP 编码保护。将编码后的数据粘贴到工具中批量解码,还原为可读的原始内容,省去逐条手动替换的繁琐操作。

🔐

协议调试与测试

测试 SMTP 或 POP3 协议交互时,原始通信日志中包含 QP 编码的邮件正文。将日志中的编码片段复制到工具解码,即时查看实际传输的文本内容,快速定位协议实现中的字符编码错误。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具竞品 A (Online QP Converter)传统方法 (邮件客户端)
数据隐私纯浏览器端处理,文件/文本不上传服务器需将文本粘贴至网页,存在数据被服务器记录的风险依赖邮件客户端软件,数据存储在本地设备
处理速度即时,1 秒内完成编解码取决于服务器响应,通常 2-5 秒取决于邮件客户端性能,通常即时但需手动操作
离线可用完全离线,无需网络必须联网必须安装客户端,离线可用
批量处理单次输入,支持大文本单次输入,通常有字符数限制支持批量邮件处理,但操作复杂
平台依赖跨平台,任何现代浏览器跨平台,任何现代浏览器依赖特定操作系统(如 Outlook 仅 Windows/Mac)
学习成本零学习成本,粘贴即用零学习成本,粘贴即用需了解邮件客户端中 QP 编码的查看/导出功能

使用指南

上手步骤 · 输入输出 · 避坑提示

使用步骤

  1. 在「编码」输入框粘贴或输入原始文本(支持 ASCII 及非 ASCII 字符)
  2. 点击「编码」按钮,工具将文本转换为 Quoted-Printable 格式(=XX 编码)
  3. 在「解码」输入框粘贴 QP 编码字符串(如 =E4=BD=A0=E5=A5=BD)
  4. 点击「解码」按钮,工具还原为原始文本
  5. 点击「复制结果」按钮,将编码或解码结果复制到剪贴板

输入输出示例8 个典型场景,覆盖常规、边界与易错

输入输出说明
Hello World!Hello World!典型场景:纯 ASCII 文本,QP 编码后无变化
中文测试=E4=B8=AD=E6=96=87=E6=B5=8B=E8=AF=95典型场景:中文字符被编码为 UTF-8 字节的十六进制
a b c da b c d边界 case:制表符和换行符保持原样,不编码
=E4=B8=AD=E6=96=87中文典型场景:解码时正确还原已编码的中文字符
A line with a trailing spaceA line with a trailing space=20边界 case:行尾空格被编码为 =20,防止传输中被截断
=E4=B8=AD=E6=96=87=E6=B5=8B=E8=AF=95中文测试典型场景:解码一段完整的 QP 编码文本
Line1 Line2Line1 Line2边界 case:CRLF 行结束符保持原样,不编码
=3D=易错 case:等号本身编码为 =3D,解码时还原为 =

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 把非 ASCII 字符直接放入 QP 编码结果

错误
=E4=B8=AD=E6=96=87
修复
=E4=B8=AD=E6=96=87 是正确的 QP 编码,但用户误以为可以直接写中文

QP 编码只允许 ASCII 字符,非 ASCII 字符必须用 =XX 形式编码。直接写中文会导致邮件客户端乱码或解析失败。

2. 把 QP 编码结果当作 Base64 解码

错误
用 Base64 解码器处理 =E4=B8=AD
修复
用 QP 解码器处理 =E4=B8=AD

QP 和 Base64 是完全不同的编码方案。QP 用 =XX 表示字节,Base64 用 A-Za-z0-9+/= 表示。混淆会导致乱码。

3. 编码时忘记处理空格

错误
Hello World 编码为 Hello=20World(正确)但用户写成 Hello World
修复
Hello World → Hello=20World

QP 编码中,空格必须编码为 =20,而不是直接保留空格。否则某些邮件客户端会丢失空格或截断。

4. 解码时误把 = 当作普通字符

错误
输入 =E4=B8=AD 但用户只粘贴了 E4B8AD(去掉 =)
修复
输入 =E4=B8=AD 完整字符串

QP 编码中 = 是转义标记,去掉 = 后解码器无法识别字节边界,会输出乱码或报错。

5. 编码时行尾未加软换行(soft line break)

错误
一行超过 76 个字符的 QP 编码结果(如 =E4=B8=AD=E5=9B=BD... 共 80 字符)
修复
每 76 个字符插入 = 加换行(RFC 2045 要求)

QP 编码标准(RFC 2045)规定每行不超过 76 个字符。超长行会被邮件服务器截断或拒绝。

6. 把 QP 编码结果直接放入 HTML 页面

错误
<p>=E4=B8=AD=E6=96=87</p>
修复
<p>中文</p>

QP 编码是邮件传输编码,不是 HTML 实体编码。在 HTML 中直接使用 QP 编码结果不会显示为中文,而是显示原始字符串。

7. 编码时把 = 本身当作普通字符

错误
输入 3=5 编码为 3=35(错误)
修复
3=5 → 3=3D5

QP 编码中 = 是转义字符,本身必须编码为 =3D。否则解码器会把 = 后的两个字符当作十六进制字节值。

8. 解码时误用 UTF-8 以外的编码

错误
用 GBK 解码 =E4=B8=AD(这是 UTF-8 编码的 '中')
修复
用 UTF-8 解码 =E4=B8=AD

QP 编码只处理字节,不处理字符编码。解码后必须用正确的字符编码(通常是 UTF-8)解释字节序列,否则显示乱码。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

编码: =XX (XX 为字节十六进制值); 解码: 将 =XX 还原为对应字节

变量说明

  • XX — 字节的十六进制表示(大写)
  • = — 转义标识符,后跟两位十六进制

示例

编码:文本 "中文" 的 UTF-8 字节为 E4 B8 AD E6 96 87,编码后为 =E4=B8=AD=E6=96=87。解码:将 =E4=B8=AD=E6=96=87 还原为字节序列 E4 B8 AD E6 96 87,再解码为 UTF-8 文本 "中文"。

适用范围

适用于邮件正文(RFC 2045/2047),仅对非 ASCII 字节(>127)或特殊字符(如 =)进行编码。ASCII 可打印字符(33-126,除 = 外)保持原样。

原理图

原始文本含特殊字符 / 非 ASCIIQP 编码 / 解码浏览器内 JavaScript 计算编码 / 解码结果可直接用于邮件正文编码示例输入:中文「你好」→ 编码后:=E4=BD=A0=E5=A5=BD输入:长行(>76字符)→ 自动插入软换行 =CRLF+空格解码:将 =XX 形式还原为原始字节(UTF-8 / ISO-8859-1)
用户输入 本地处理 输出结果

开发者集成

3 种主流语言 · 复制即用

import quopri

# 编码:bytes → QP 字符串
text = "hello, 世界"
encoded = quopri.encodestring(text.encode("utf-8")).decode("ascii")
print(encoded)  # hello, =E4=B8=96=E7=95=8C

# 解码:QP 字符串 → bytes
decoded = quopri.decodestring(encoded.encode("ascii")).decode("utf-8")
print(decoded)  # hello, 世界
package main

import (
	"fmt"
	"mime/quotedprintable"
	"strings"
)

func main() {
	// 编码
	text := "hello, 世界"
	var buf strings.Builder
	w := quotedprintable.NewWriter(&buf)
	w.Write([]byte(text))
	w.Close()
	encoded := buf.String()
	fmt.Println(encoded) // hello, =E4=B8=96=E7=95=8C

	// 解码
	r := quotedprintable.NewReader(strings.NewReader(encoded))
	decoded := make([]byte, len(text))
	n, _ := r.Read(decoded)
	fmt.Println(string(decoded[:n])) // hello, 世界
}
// 浏览器环境(无标准库,用 TextEncoder/Decoder 模拟)
// 编码:非 ASCII 字符转为 =XX 格式
function qpEncode(str) {
  return Array.from(new TextEncoder().encode(str))
    .map(b => b > 127 || b === 61 ? '=' + b.toString(16).toUpperCase() : String.fromCharCode(b))
    .join('');
}

// 解码:=XX 转回字节
function qpDecode(str) {
  const bytes = str.replace(/=([0-9A-Fa-f]{2})/g, (_, h) => String.fromCharCode(parseInt(h, 16)));
  return new TextDecoder().decode(new Uint8Array([...bytes].map(c => c.charCodeAt(0))));
}

const text = 'hello, 世界';
const encoded = qpEncode(text);
console.log(encoded); // hello, =E4=B8=96=E7=95=8C

const decoded = qpDecode(encoded);
console.log(decoded); // hello, 世界

常见问题

7 个高频疑问

Quoted-Printable 编解码怎么用?我直接把邮件原文复制进去就行吗?
是的。如果是编码,在输入框粘贴纯文本(如中文、特殊符号),点击「编码」按钮,输出区即得到 QP 编码结果,可直接用于邮件正文。如果是解码,粘贴形如 =E4=B8=AD=E6=96=87 的 QP 编码字符串,点击「解码」恢复原文本。注意:QP 编码通常出现在 MIME 格式邮件的正文部分,复制时确保只复制 = 开头的编码片段,不要包含邮件头或边界标记。
为什么我解码后的中文还是乱码?
乱码通常是编码字符集不匹配造成的。QP 编码本身只处理字节,不指定字符编码。如果原始邮件使用 UTF-8 编码,但浏览器默认按 GBK 或 ISO-8859-1 解码,就会显示乱码。本工具解码时使用 UTF-8 作为默认字符集(现代邮件最常用)。如果原始邮件是 GBK 或 Shift-JIS 编码,请先确认邮件头中 charset 字段的值,再用支持指定字符集的工具转换。
这个工具处理大文件(比如 10MB 邮件正文)会卡死吗?
因为所有处理都在浏览器内完成(纯前端 JavaScript),不依赖服务器,大文本确实会消耗本地 CPU 和内存。10MB 纯文本在普通电脑上通常 1-3 秒完成,但移动端或低配设备可能卡顿几秒。建议分批次处理,单次不超过 5MB。如果频繁处理大文件,可考虑使用命令行工具(如 Python 的 quopri 模块)效率更高。
Quoted-Printable 和 Base64 编码有什么区别?什么时候用哪个?
QP 编码主要针对 7 位 ASCII 邮件传输协议设计,只对非 ASCII 字符(如中文、特殊符号)进行 =XX 转义,可读性好,人眼能部分识别原文。Base64 则将整个数据块重新编码,效率更高(开销约 33% vs QP 的 50-100%),但完全不可读。实际使用场景:邮件正文含大量中文时用 QP,附件或二进制数据用 Base64。邮件客户端通常自动选择,手动编解码时根据需求选择。
我复制邮件里的 QP 编码段,但解码后缺字符或结果不对,是工具问题吗?
大概率是复制的片段不完整或包含无关字符。QP 编码要求每行不超过 76 个字符(RFC 2045),长行会被软换行(行尾 = 表示续行)。如果只复制了断行的一部分,解码会失败。建议:在邮件原始内容中选中从 = 开头的整段(包括所有 =XX 和换行符),完整粘贴。本工具会忽略行尾空格和空白行,但不会自动拼接被截断的行——需要手动确保每行完整。
这个工具会把我输入的邮件内容上传到服务器吗?隐私安全吗?
不会。所有编解码操作完全在浏览器本地运行,不发送任何数据到服务器。可以验证:打开浏览器开发者工具(F12)→ Network 标签页,输入内容并点击按钮后,观察是否有任何网络请求发出。即使断网,工具也能正常使用。处理完成后,关闭页面或刷新,输入内容即从内存清除。
为什么我编码后的结果比原文大了很多?正常吗?
正常。QP 编码对非 ASCII 字符(如中文)每个字节编码为 =XX 形式(3 个字符),而中文 UTF-8 编码通常占 3 个字节,所以一个中文会变成 9 个字符。纯英文或 ASCII 字符保持不变。假设原文全是中文,编码后体积大约是原文的 3 倍。如果原文包含大量 ASCII 符号(如空格、等号),它们也会被编码(空格可保留或编码为 =20,等号必须编码为 =3D),体积还会增加。这是 QP 编码的固有特性,无法避免。
选择 打开 +新窗口 esc关闭