EUC-JP

一种在 UNIX 系统上广泛使用的日语字符编码,属于扩展 Unix 编码家族。

EUC-JP 是为在 UNIX 系操作系统上处理日语文本而设计的字符编码。在 IANA 的字符集登记簿中,它以 Extended_UNIX_Code_Packed_Format_for_Japanese 这一正式名称登记,而写进 HTTP 标头或 meta charset 时推荐的写法是 EUC-JP。从 1980 年代后期到 1990 年代,它在日本的 UNIX 社区中作为标准被采用。正式地说,它用 2 个字节对 JIS X 0208 所定义的汉字集合进行编码,再与兼容 ASCII 的单字节区域组合起来,从而提供了高效处理英日混合文本的机制。

EUC-JP 的编码结构,特点在于可以凭字节值的范围判别字符种类。ASCII 字符是 0x00-0x7F 的 1 个字节,JIS X 0208 的汉字、平假名、片假名用 0xA1-0xFE 的 2 个字节表示。此外,JIS X 0201 的半角片假名以 0x8E 为首字节占 2 个字节,JIS X 0212 的补充汉字以 0x8F 为首字节占 3 个字节。正因为字节值的划分如此明确,Shift_JIS 中成为麻烦的「5C 问题」在这里不会发生。Shift_JIS 中存在「ソ」(83 5C)、「表」(95 5C) 这样第 2 字节与反斜杠 (0x5C) 取同一值的字符,按字节扫描的程序会把第 2 字节误认成转义字符。而 EUC-JP 从第 2 字节起不会出现小于 0x80 的字节,所以这种误认本身就无从发生。

在 Linux 和 FreeBSD 等 UNIX 系操作系统上,直到 2000 年代前期 EUC-JP 都作为默认区域设置被广泛使用。在服务器用途上尤其受重视,因为它与 C 语言的字符串处理函数相性良好,grep、sed 等文本处理工具能够稳定运行。日本的大学与研究机构的服务器、ISP 的邮件服务器等许多基础设施,都曾有过以 EUC-JP 为前提构建的时代。

与 Shift_JIS 相比,EUC-JP 在程序处理的方便程度上占优。Shift_JIS 在 MS-DOS 和 Windows 上被作为标准使用,但由于第 2 字节含有与 ASCII 重叠的字节值,与路径分隔符、转义字符的冲突频繁发生。而 EUC-JP 的第 2 字节始终在 0xA1 以上,因此不会出现这类冲突。不过 EUC-JP 并不是 Windows 的标准代码页,所以在以 Windows 为中心的环境里,需要中间夹一道与 Shift_JIS (CP932) 的转换。

到 2026 年时,向 UTF-8 的迁移已基本完成,新的系统或应用程序已没有采用 EUC-JP 的理由。但在维护遗留系统、分析旧日志文件、浏览邮件列表存档等场合,实务中遇上 EUC-JP 的情形依然存在。用 iconv 命令或 Python 的 codecs 模块可以实现 EUC-JP 与 UTF-8 的相互转换,不过从 UTF-8 回到 EUC-JP 的方向,必须以字符会丢失为前提来对待。带圈数字「①」和全角波浪号 (U+FF5E) 并不存在于 EUC-JP 的基本转换表中,转换时会变成报错或替换字符。另外 JIS X 0212 的补充汉字,在 Web 浏览器所遵循的规范里只被列为读入 (解码) 的对象而不在写出 (编码) 的对象之内,因此存在读得进来的字符却无法用同一编码写回去的不对称性。

从字符计数的角度看,理解 EUC-JP 编码文本中字节数与字符数的关系很重要。ASCII 字符是 1 字节 = 1 字符,JIS X 0208 的汉字、平假名、全角片假名是 2 字节 = 1 字符。需要留意的是半角片假名和补充汉字:半角片假名在 Shift_JIS 中 1 个字符 1 个字节,在 EUC-JP 中却因为加了 0x8E 而变成 2 个字节;JIS X 0212 的补充汉字 1 个字符要占 3 个字节。用字节数除以 2 来推算字符数的捷径,一旦混入这两类字符就会失效。100 个日语字符的文本在 EUC-JP 下是 200 个字节,在 UTF-8 下是 300 个字节,所以以日语为主的文本用 EUC-JP 时文件更小。要准确掌握遗留数据的字符数,可靠的做法不是从字节数逆算,而是先解码成 UTF-8 之类的编码再来数。

分享这篇文章