原理解说发布日期 阅读时间约 8 分钟

%E3%81%82、\u3042、\343 的读法:URL、JSON、Git 中日语变成编码的原因

复制 URL 得到“%E6%96%87%E5%AD%97”,查看 API 返回值看到“\u6587\u5b57”,Git 的文件名显示成“\346\226\207”。这些看起来都像乱码,其实日语并没有损坏,只是把日语的字节或编号用英文数字写了出来,你看到的正是这种“编码”。本文介绍 9 种常见写法的辨认方法和读法、它们出现的场合,以及让显示变回日语的设置。

编码不是乱码,而是“日语的一种写法”

乱码是搞错字符编码、读成了别的字符的状态。而 %E3%81%82、\u3042 则是为了在只能用英文数字的地方写日语,特意替换成英文数字的结果。只要知道写法的规则,就能一个字不少地还原成日语。

大致可分为两类:写“字符的编号(Unicode 码位)”的方式,和写“字符的字节(用 UTF-8 等保存时的数字)”的方式。平假名“a”的 Unicode 编号是 U+3042(十进制 12354),UTF-8 字节是 E3 81 82。记住这两组数字,就能很快看出是哪种写法。

9 种写法速查表

写法示例(“文字”等)内容常见场合
URL 编码%E6%96%87%E5%AD%97UTF-8 字节URL、搜索词、下载的文件名
URL 编码(旧形式)%95%B6%8E%9AShift_JIS 字节日本旧网站、论坛的 URL
Unicode 转义\u6587\u5b57Unicode 编号(十六进制)JSON、JavaScript、API 返回值
八进制转义\346\226\207\345\255\227UTF-8 字节(八进制)git status、git diff 中的文件名
字节转义\xe6\x96\x87\xe5\xad\x97UTF-8 字节(十六进制)Python 的 bytes、日志、错误信息
HTML 字符引用文字 / 文字Unicode 编号(十进制、十六进制)HTML 源码、RSS、HTML 邮件
Quoted-Printable=E6=96=87=E5=AD=97UTF-8 字节邮件正文的源码
Punycodexn--wgv71a119e.jp日语域名转换后的结果日语域名的 URL(日本語.jp)
Base645paH5a2X5YyW44GR用 64 种字符表示 UTF-8 字节邮件附件和正文、API 数据

表中的示例都放进乱码还原·解读工具的“读取转义”确认过。Base64 的示例还原成日语的“乱码”一词,其他还原成“文字”(Punycode 还原成“日本語.jp”)。文本中混有多种写法时,工具也会逐一找出并读取。

URL 中的 %E3%81%82:复制日语 URL 时

URL 只能使用英文数字和部分符号,所以日语的 UTF-8 字节要用“%”加两位十六进制数来表示。一个日语字符在 UTF-8 中是 3 个字节,所以 3 个 %XX 对应 1 个字符。4 个字符的日语单词“乱码”会写成“%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91”,共 36 个字符。

  • 即使浏览器地址栏显示日语,复制到聊天或邮件时也会变成 %XX 的形式
  • 以 %E3 开头的多为平假名和片假名,以 %E4~%E9 开头的多为汉字
  • 如果 %82、%83 很多,看起来 2 个 %XX 对应 1 个字符,可能是用 Shift_JIS 写的旧 URL
  • “+”有时表示空格(如搜索表单发送的 URL)

把 URL 发给别人时,保持 %XX 的形式更可靠。还原成日语的 URL,在某些应用中链接可能会中途断开。

JSON 中的 \u3042、Git 中的 \343、Python 中的 \xe3

在编程中,日语常常不直接输出,而是写成转义形式。下面每种情况都可以通过显示设置变回日语。

  • JSON 的 \u3042:用 4 位十六进制数写 Unicode 编号。Python 输出 JSON 时加上 ensure_ascii=False,就能直接输出日语。表情符号写成一对,如“🍣”(🍣)
  • Git 的 \343\201\202:git status 等把日语文件名用八进制显示。设置 git config --global core.quotepath false 后就会显示日语
  • Python 的 \xe3\x81\x82:直接显示 bytes 类型。用 .decode('utf-8') 转成字符串就是日语
  • HTML 的 あ、あ:用十进制或十六进制写 Unicode 编号。浏览器显示为平假名“a”,但以文本形式查看源码或 RSS 时,看到的就是编码

以 xn-- 开头的是国际化域名

“日本語.jp”这样的日语域名,因 DNS 的机制需要转换成英文数字来处理。这种转换方式就是 Punycode,转换后带有“xn--”。“xn--wgv71a119e.jp”就是“日本語.jp”。

为了防止利用外观相似字符的仿冒,浏览器有时会特意用 xn-- 的形式显示日语域名。对于陌生 xn-- 域名发来的邮件或链接,最好还原后确认域名是否真的正确。

如果夹杂的不是编码,而是“縺”“ã”这样真正的乱码,请在乱码类型速查表中确认类型。邮件主题中的 =?UTF-8?B?…?= 也属于这一类,详见邮件主题乱码的原因与解决方法。

常见问题

如何把 URL 中的 %E3%81%82 还原成日语?
把 % 后面的两位十六进制数作为 1 个字节收集起来,按 UTF-8 读取。%E3%81%82 是平假名“a”。日语是 3 个 %XX 对应 1 个字符。粘贴到乱码还原·解读工具的“读取转义”,就能一次还原。
JSON 中的 \u3042 是什么?
它是用 4 位十六进制数写 Unicode 编号的 Unicode 转义,\u3042 是平假名“a”。JSON 常用这种设置输出日语。表情符号用一对表示 1 个字符,如 🍣。
Git 把日语文件名显示成 \343\201\202 这样,怎么回事?
Git 把日语文件名的 UTF-8 字节用八进制显示了。设置 git config --global core.quotepath false 后,git status 等就会直接显示日语。
以 xn-- 开头的 URL 危险吗?
xn-- 表示把日语等国际化域名转换成了英文数字,它本身并不危险。不过它也可能被用于利用外观相似字符的仿冒,还原后确认域名会比较放心。

本文介绍的工具

相关文章