中文转义

中文与 \uXXXX 转义、HTML 数字实体、URL 百分号编码互转,顺便把「看起来像拉丁字母」的乱码还原回中文。

输入
输出

      

四种写法,同一个字

很多通道只保证 ASCII 安全:HTTP 头、Cookie、老式日志系统、Java 的 properties 文件、只认 US-ASCII 的构建脚本。中文要安全穿过这些通道,就得先「ASCII 化」。常见做法有四种,本质都是把字符换成能在任何地方原样传输的字符组合。

写法「中文」的样子常见于
原始文本中文页面、终端、现代编辑器
Unicode 转义\u4e2d\u6587JSON / JS 字符串字面量、Java 源码、部分日志
HTML 实体中文 或 中文HTML 源码、老邮件模板
URL 百分号%E4%B8%AD%E6%96%87URL 查询串、表单、Cookie

三者的数字并不通用:转义写的是 UTF-16 码元,HTML 实体写的是 码点,百分号编码写的是 UTF-8 字节。同一个「中」字,转义是 4e2d,实体是 20013,百分号是三组字节 E4 B8 AD——改格式必须整个转换,不能只换前缀。

emoji 为什么要写成两个 \uXXXX

Unicode 转义按 UTF-16 码元书写,每四位一组。码点超过 U+FFFF 的字符(emoji、部分生僻字)在 UTF-16 里要占两个码元,所以一个 🐟 会写成 \ud83d\udc1f 两组,看起来像两个字符,其实是一个。解码时它们会自动拼回一个完整的字符。HTML 实体则直接写码点,🐟 是 🐟,一个实体就够。所以同一个 emoji 在两种写法里的长度完全不同,这不是工具算错了。

中文乱码的三种成因

  1. 编码不一致(GBK 与 UTF-8 互相误读)。字节按一种编码写、却按另一种读。看到「锟斤拷」这类说明原始信息已经丢失(错误字节被替换成了固定字符),任何工具都还原不了;看到「中文」这类拉丁字母混排,说明是 UTF-8 被当成 Latin-1 或 Windows-1252 读了,勾选「先修复 UTF-8 乱码」即可还原。
  2. Unicode 转义没有被解释。接口返回的是 \u4e2d\u6587 字面量,前端原样打印到页面上。把输入格式选成 Unicode 转义,输出格式选纯文本。
  3. URL 百分号编码没有被解码。链接里的 %E4%B8%AD 被原样抄进了文档或日志。选 URL 百分号编码 → 纯文本,或者去用 URL 编解码。
已知边界 HTML 实体只解码数字实体(十进制与十六进制)和一小批常见命名实体(amp、lt、gt、quot、nbsp、copy、hellip 等),其余命名实体原样保留,不会被误改。GBK / GB18030 造成的乱码不在本工具能力范围内。

常见问题

为什么一个 emoji 会变成两个 \uXXXX?
因为 Unicode 转义按 UTF-16 码元写,而 emoji 的码点大于 U+FFFF,UTF-16 需要两个码元(代理对)。这是规范行为,Java、JavaScript、JSON 都这么写,解码时会自动还原。
\u4e2d、中、%E4%B8%AD 有什么区别?
三者分别用 UTF-16 码元、码点、UTF-8 字节表示同一个字,数字都不一样,不能只换前缀。要跨格式转换,用这个工具在四种格式之间互转,不要手工替换。
乱码看起来像拉丁字母,能还原吗?
能。像「中文」这种是 UTF-8 字节被当成 Latin-1 / Windows-1252 读出来的,勾选「先修复 UTF-8 乱码」就会先按字节还原再转换。这类乱码串中间夹着一个不可见的软连字符(就是上面的 ­),复制时被丢掉的话就还原不了。
HTML 实体输出用十进制还是十六进制?
默认十进制,例如输出 中;勾选「HTML 用十六进制」后输出 中。两种浏览器都认,选哪个主要看团队习惯。
「仅转义非 ASCII」是干什么的?
默认开启,只转义中文等非 ASCII 字符,英文数字和标点保持原样,输出还能直接读。关掉之后每个字符都会被转义。

相关工具

URL 编解码encodeURIComponent 与 encodeURI 两种模式 数据脱敏手机号、身份证、邮箱、银行卡、IP、姓名打码 JSON 格式化格式化、压缩、校验 JSON