什么编码会把「测试」变成「娴嬭瘯」?
UTF-8 → GBK UTF-8 的字节被当成 GBK 读。6 个 UTF-8 字节(E6 B5 8B E8 AF 95)被重新切成了 3 个 GBK 字符。
粘贴乱码即可自动还原原文。工具枚举 UTF-8、GBK、Big5、Shift_JIS、EUC-KR 等编码组合并按可信度排序,标出哪一条经过往返校验、能逐字复现。同时提供各编码下的字节对照与 hex 反解。免费在线,全程在浏览器内完成,内容不上传。
把乱码粘贴进来。工具会试遍所有可能的编码链并给结果排序——你不需要知道是哪种编码出的问题。
测试
UTF-8 → GBK
娴å¬ç˜¯
Windows-1252 / Latin-1 → UTF-8
测试
Windows-1252 / Latin-1 → GBK
测试
Windows-1251 → GBK
一次看到同一段文本在所有常见编码下的字节——需要确认数据库或协议里究竟存了什么时很有用。
| 编码 | 字节数 | 十六进制 |
|---|---|---|
| UTF-8 | 6 | E4 B8 AD E6 96 87 |
| GBK | 4 | D6 D0 CE C4 |
| GB18030 | 4 | D6 D0 CE C4 |
| Big5 | 4 | A4 A4 A4 E5 |
| Shift_JIS | 4 | 92 86 95 B6 |
| EUC-KR | 4 | F1 E9 D9 FE |
由 Go Tools 工程团队构建并验证。
UTF-8 → GBK UTF-8 的字节被当成 GBK 读。6 个 UTF-8 字节(E6 B5 8B E8 AF 95)被重新切成了 3 个 GBK 字符。
UTF-8 → Windows-1252 同样这串 UTF-8 字节,被当成 Windows-1252 读。因为它是单字节编码,6 个字节各自变成一个字符。
不可恢复 救不了。那些字节在解码时已被丢弃。尽量从周围文字还原,其余部分只能回源数据取。
3 与 2 字节 UTF-8 里 3 个,GBK 与 Big5 里 2 个。按字节而非字符来定字段长度时,这个差别是截断故障的常见来源。
乱码是用一种字符编码写出、却用另一种字符编码读入的结果。字节本身完好无损,错的只是解释方式。这个区别正是还原之所以可能的全部原因:只要判断出是哪种编码写的、被哪种编码误读,就能把这个错误倒着执行一遍,拿回原文。
这个词的日文写法是「文字化け」,大意是「字符变形」。它之所以成为通用术语,是因为在 Unicode 普及之前,日文计算环境里这个问题极其普遍。中日韩文本比拉丁文本更容易中招,原因是结构性的:这些语言必须用多字节编码,而不同的多字节编码对「字节该怎么分组」意见不一致。拉丁文本大多落在 ASCII 范围内,而所有编码在 ASCII 上的约定都是一样的。
还原只在一种情况下失败:解码器遇到在自己编码里没有定义的字节时,不会保留它们,而是替换成 U+FFFD 后丢弃。这些字符永久丢失,其余一切都是可逆的。
// The mistake, in three lines of JavaScript
const bytes = new TextEncoder().encode('测试'); // UTF-8: E6 B5 8B E8 AF 95
new TextDecoder('gbk').decode(bytes); // '娴嬭瘯' ← mojibake
new TextDecoder('windows-1252').decode(bytes); // '测试' ← same bytes, other mistake 粘贴乱码,工具替你枚举编码链。UTF-8、GBK、GB18030、Big5、Shift_JIS、EUC-KR、Windows-1252、Windows-1251 之间「写入编码 × 读出编码」的每一种组合都会试一遍。
只有当还原结果沿同一条链倒推能逐字复现你的输入时,才会标为无损。这是确定性检查——只给一个排序,你就无从判断哪些结果值得相信。
每条候选都注明是哪种编码写的、被哪种编码误读。这才是修复上游所需要的信息,否则下周还得对着新数据再修一遍同样的字符串。
输入里若已含替换符,工具会直接说明,并把所有候选标为部分还原。解码时被销毁的信息不会回来,假装它能回来只会浪费一个下午。
把同一段文本在各编码下的十六进制字节并排列出,也支持把 hex 反向解成文字。核对字段长度、读抓包结果、检查 BLOB 内容时都用得上。
解码用的是浏览器自带的 TextDecoder,不上传、不存储、不改写 URL——需要还原的乱码通常直接来自生产环境,这一点很关键。
娴嬭瘯
测试
这两个汉字本来以 UTF-8 正确存储(字节为 E6 B5 8B E8 AF 95),随后某个程序把这 6 个字节当成 GBK 来读。GBK 是两字节一组,于是 6 个字节被切成 3 个字符,字数都对不上了。老版 Windows 程序打开 UTF-8 文件、或者数据库连接串写了 characterEncoding=gbk 而数据实为 UTF-8,出来的就是这个样子。
测试
测试
同样的字节,另一种误读。Windows-1252 是单字节编码,所以 6 个 UTF-8 字节各自变成了一个字符。拉丁语系遇到的多是这一种:café 变成 café,naïve 变成 naïve。特征是成对出现的 Ã、Â、â 和莫名其妙的标点符号。
B2 E2 CA D4
测试
有时候面对的不是乱码文本,而是抓包结果或者 BLOB 字段里的一段十六进制。把 hex 粘进第二个区块、选好编码即可。B2 E2 CA D4 在 GBK 里就是「测试」——同样两个字在 UTF-8 下要占 6 个字节(E6 B5 8B E8 AF 95),而在 Windows-1252 里根本无法表示。
鏁版嵁搴�
(只能部分还原)
「数据库」以 UTF-8 写出、被当成 GBK 读,但最后一组字节在 GBK 里没有定义,解码器把它替换成了 U+FFFD。那个字节已经没了。工具会如实标出这种情况,而不是硬猜一个像样的答案——前面的「数据」仍能还原,最后一个字则必须回到源数据去取。
直接粘进来,不用先判断编码。一小段就够,十几个字符通常足以锁定编码链。
无损=沿同一条链倒推能逐字复现你的输入;部分=对不上,只能当线索。
每条候选都标出原文的真实编码与误读它的编码。这告诉你上游该改哪里,而不只是这段文字原本是什么。
第二个区块能把任意文本按各编码列出字节,也能把 hex 反解成文字。核对字段长度、排查报文时用它。
文本显示正常却照样转一遍,反而会亲手制造出想要避免的乱码。先确认当前状态,另外注意区分:缺字体渲染成方块(□□□),编码问题渲染成别的字。
iconv -f UTF-8 -t GBK correct.txt > broken.txt
# 先确认当前编码 file -I correct.txt # charset=utf-8 → 无需转换
改 MySQL 列的声明字符集,并不会重新编码里面已有的字节。把 latin1 的数据声明成 utf8,服务器会交出并非合法 UTF-8 的字节,驱动随即用 U+FFFD 替换——数据就此被销毁。
ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;
-- 先过一次二进制类型,让字节被保留而不是被重新解释 ALTER TABLE t MODIFY c VARBINARY(255); ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4;
标为部分的候选没有通过往返校验。它值得跟进,但不是一个可以直接写回数据库的答案。如果一条无损结果都没有,多半是输入本身已经丢了信息,应该回到源字节去处理。
// 不管徽章说什么,取第一条 db.update(row.id, candidates[0].text);
// 只写回通过往返校验的结果 if (candidates[0].lossless) db.update(row.id, candidates[0].text);
在 Python 3 里对已经是 bytes 的东西调 encode、或对已经是 str 的东西调 decode 会直接抛异常,而不是像 Python 2 那样静默地绕一圈 ASCII。在边界处解码一次,之后一律按文本处理。
text = raw.decode('utf-8').encode('gbk').decode('utf-8') # 在边界处解码一次,用文件真正使用的编码
with open(path, encoding='gbk') as f:
text = f.read() VARCHAR(50) 变成截断故障的那类原因。TextDecoder。反方向要麻烦些——TextEncoder 只支持 UTF-8,所以工具通过遍历字节空间、逐个询问解码器的方式反推出编码表。这样映射永远与浏览器自身行为一致,也不必向你的设备下发任何映射数据。Content-Type、文件打开调用、CSV 导出选项。每一处依赖「系统默认编码」的地方,都是同一个 bug 换台机器就会复发的地方。utf8 每个字符最多存 3 字节,emoji 和部分生僻汉字会被静默截断。utf8mb4 才是真正的 UTF-8。这类损坏与乱码不同,本工具救不了——那些字节是真的没了。U+FFFD(显示为 �)并丢弃。这一步是有损且不可逆的。如果你的文本里含有 �,那几个字符无论用什么工具都找不回来了。本页会直接告诉你这一点,而不是生成一个看起来很有把握的猜测。 iso-8859-1 和 latin1 都当作 windows-1252 的别名。两者只在 0x80–0x9F 这一段不同:真正的 ISO-8859-1 那里是控制字符,Windows-1252 那里是破折号、弯引号这类可打印符号。而乱码里冒出来的恰恰就是这些可打印符号,所以 Windows-1252 更有用,本工具把两个名字合并为一项。 TextDecoder 在本地完成,不发网络请求、不写入存储、也不改写 URL。这一点对本工具比对其他工具更重要:需要还原的乱码,来源几乎总是生产日志、客户记录或数据库导出——正是最不该粘进服务端工具的那类内容。 iconv -f GBK -t UTF-8 input.txt > output.txt,PowerShell 里是 Get-Content -Encoding Default in.txt | Set-Content -Encoding UTF8 out.txt。先把有代表性的一行粘到本页确认编码链,再去写命令——方向搞反的话,一行的小问题会变成一千行的大问题。 编码和格式化
完整 ASCII 码表:128 个字符的十进制、十六进制、八进制、二进制对照,支持字符转 ASCII 码、ASCII 码转字符双向转换。控制字符附各语言转义写法与终端 ^M 记法,并说明你会在哪儿真的遇到它。浏览器本地运行,不上传。
编码和格式化
免费在线 Base64 解码编码工具。实时转换,支持中文和 Emoji,100% 浏览器端运行,数据不离开设备,无需注册。
编码和格式化
在浏览器中把 Base64 字符串或 data URI 解码还原为图片。预览、读取尺寸与 MIME,再下载为 PNG、JPG、GIF、SVG。无需上传。
编码和格式化
在浏览器中将 CSV 转换为 JSON。支持 RFC 4180、类型推断、表头行、大整数安全。100% 隐私,无需上传。
编码和格式化
粘贴 .env 文件,立即得到 JSON。数据库密码、API 密钥和令牌绝不离开你的浏览器 — 100% 本地、零上传、免费的 dotenv 解析器。
编码和格式化
在线解码 HTML 实体、还原转义后的 HTML——免费、免注册、100% 在浏览器中运行。把命名、十进制和十六进制引用转回字符;绝不上传。