摘要
- RFC 1468 规定了一套窄而明确的七位切换配置:正文从 ASCII 开始,四种转义序列选择 ASCII、JIS X 0201 Roman 或两个版本的 JIS X 0208;使用双字节字符的每一行都必须在 CRLF 之前退出双字节状态。
- MIME 中的
ISO-2022-JP只声明预期的解码契约;它不能证明正文符合语法、中继保留了转义序列、解码器得到相同字符,更不能证明读者看见了相同字形。
一封邮件里最重要的字节,可能从不出现在屏幕上。
1993 年 6 月发布的 RFC 1468 记录了源于 JUNET、并已在日本多个 IP 社群使用的编码方式。它把这套方式命名为 ISO-2022-JP,供 MIME 的 charset 参数使用。名称解决了一个真实问题:收件端不必再靠猜测判断应调用哪套规则。但它没有把日文文本压缩成“一张字符表”。同一个字节值会因先前出现的转义序列而改变含义,解码器必须记住自己此刻处在哪个状态。
因此,RFC 1468 的历史意义不只是“邮件终于能写日文”。它把互操作性放进了一条有状态的七位字节流,并试图把状态传播的范围限制在旧邮件工具能够承受的位置。
四个入口,共用一段历史
正文从 ASCII 状态开始。ESC $ B 把后续字节指定为 JIS X 0208-1983,ESC $ @ 选择 1978 版;两者之下,每个字符都由两个字节组成。ESC ( B 返回 ASCII,ESC ( J 切换到 JIS X 0201 Roman。
这四段序列不是附在字符旁边的注释,而是会改变后续读取规则的操作。若当前状态是 JIS X 0208,两个处于 33 至 126 范围内的字节可以组成一个字符;复位到 ASCII 后,相同数值不再组成同一个对象。仅看当前位置的字节,无法完整回答“这是什么字符”。答案依赖此前最后一次合法切换。
两个单字节状态也不能偷换。JIS X 0201 Roman 在反斜杠与日元符号、波浪号与上划线两个位置上不同于 ASCII。某台终端使用的字体也许把差异遮住,但下一台机器、另一套字体或转换器仍可能区分它们。RFC 还明确排除了 JIS X 0201 的 Kana 集。名称中的 “JP” 不是对任何本地日文编码的概括授权。
形式语法把 ESC、SI、SO 排除在普通单字节字符之外,正是为了守住这条边界:状态控制字节不能在需要时又被当成普通文字。名称的价值来自背后机器足够小、足够确定,而不是来自名称足够宽泛。
每一行都要自己找到回程
如果一行出现 JIS X 0208 字符,RFC 要求在 CRLF 之前切回 ASCII 或 JIS X 0201 Roman。下一行从前一行结束前选定的单字节状态开始;整篇正文最终必须处于 ASCII。
这个要求看似重复。连续多行日文会反复写入切换与复位序列,增加本来可以省掉的字节。它换来的却是有限的重新同步能力。引用程序在新行开头插入 > 时,不会把一个看似 ASCII 的符号塞进双字节字符中间。随机定位到后面一行的查看器,不必从邮件开头一路追踪状态。某行受损,也不必让之后所有行永久继承错误的双字节解释。
复位并非万能。行尾也可回到 JIS X 0201 Roman,所以程序仍要处理它与 ASCII 的两个差异;规范也没有统一所有畸形输入的恢复策略。但双字节状态被禁止悄然越过行界。CRLF 因而不只是排版符号,还是解释权的边界。
这体现了最小初始规范的力量。邮件路径上的每一台服务器都不必理解日文,只需保留一个受限的七位对象。端点独立实现解码,发送者独立决定是否采用,公共部分只规定足以互通的状态与重启点。
七位可传,不等于内容可读
RFC 给出的 MIME 用法是 Content-Type: text/plain; charset=iso-2022-jp。由于整个表示已经是七位,单纯为了通过旧邮件路径,无需再套一层内容传输编码。
但“没有高位字节”只回答传输宽度。中继若删除 ESC、替换指定序列、在一对双字节之间换行,或把 CRLF 重新序列化,输出依然可能全部是七位,含义却已改变。载体接受哪些数值,与这些数值在什么状态下被解释,是两个问题。
文档还指出,当时 JUNET 软件若收到 Base64 或 quoted-printable 包裹的内容,会无法阅读。这里必须保留历史时态。正确应用并逆转的传输编码并不必然丢失原字节;真正的限制是 1993 年运行中的客户端未必懂得先拆除外层,再调用 ISO-2022-JP 解码器。可逆的纸面设计与已部署的软件组合并不自动相等。
后来 RFC 2046 把 charset 说明为 MIME 文本中的关键参数,并要求正文由所命名字符集的字符构成,同时继续遵守文本行规则。参数帮助程序选择契约,却不能替程序执行契约。
中继没有“看起来一样就改掉”的权限
RFC 1468 特别提醒:有些系统显示时不区分 ESC ( B 与 ESC ( J,也不区分 ESC $ @ 与 ESC $ B。即便如此,中继也不得以任何方式改动这些转义序列。
这条规则把局部视觉等价与可转移身份分开。中继屏幕上看不见差异,不代表下一收件端、归档工具或转换器也看不见。某封邮件在两个 JIS 版本下恰好呈现相同字形,也不能证明其指定历史可以被重写。当前工具的无感,不会产生替未来工具做决定的权力。
原样保存还保留了追责能力。若最终字形不同,可以分别检查发送者字节、中继保管、解码器输出与字体呈现。若中继出于“清理”目的改写序列,错误来源便被揉成一团。局部看起来更整齐的副本,可能是证据上更贫乏的副本。
当然,逐字节保管并不验证作者身份,也不证明邮件陈述为真。它只是要求中间人不把自己的显示偏好写回他人的对象。
一个行长,至少有三套坐标
RFC 建议用户把可见行长控制在约 75 到 80 列,以便引用时在行首加入符号。按其模型,一个 JIS X 0208 字符占两个字节、两个显示列;转义序列占若干字节,却不占显示列。实现者不得为了折行而劈开双字节字符。
所以同一行存在字节偏移、字符位置和显示列三套坐标。ASCII 段中它们大致同步,进入双字节状态后立即分离。按第 80 个字节截断,未必等于在第 80 列折行。先删除“不可见控制码”再验证,恰恰可能删掉后续所有字节的解释依据。
屏幕截图证明的是某个环境下的图形结果,不能反推全部输入字节。正文哈希证明的是表示相同,不能证明字体选出了什么字形。可靠证据不是挑一个看起来最直观的层,而是把各层的转换关系留下来。
登记名称,不等于运行解码器
RFC 2978 后来给出更精确的定义:charset 是把八位组序列转换成字符序列的方法,可以包含 ISO 2022 这样的复杂表切换;名称关联的定义必须完整说明映射,不能依赖未声明的外部配置。
当前 IANA Character Sets 登记表 把 ISO-2022-JP 记为 39,引用 RFC 1468 与 RFC 2237,并保存别名 csISO2022JP;ISO-2022-JP-2 则单独登记为 40。登记避免不同实现故意拿同一名字指向不同机器。它不会检查某封邮件,也不会认证某个库或测量今天的采用率。
RFC Editor 的元数据 将 RFC 1468 标为 Informational。这个状态不能被说成“无实际影响”,也不能被抬高成“互联网标准”。同理,IANA 有条目意味着名称受协调,不意味着带此标签的每个实例都合规。文献地位、名称稳定与运行结果必须分别取证。
扩大状态空间,就换一个名字
1993 年 12 月的 RFC 1554 描述实验性的多语种扩展 ISO-2022-JP-2。它加入中文、韩文、补充日文、拉丁与希腊字符的指定方式,又引入会在新行清除部分信息的第二状态域。解码器义务变大,MIME 名称也随之改变。
1997 年的 RFC 2237 以 ISO-2022-JP-1 加入 JIS X 0212 和 ESC $ ( D。它仍要求正文最终回到 ASCII,并规定若未使用补充字符,就必须采用普通 ISO-2022-JP。
新名称让新增义务对接收端可见。旧程序可以诚实拒绝,而不必在熟悉标签下猜测陌生状态。创新得以继续,旧档案的含义也不被新实现悄悄改写。
字节之后仍有现实层
这组标准能证明合规流应如何组成,不能证明某个读者实际看见了什么。审计必须分别保留 MIME 字段、原始正文、状态切换轨迹、中继转换、解码器版本、字符序列、字体与渲染结果。
Heng Lu 的三篇公开论述为这条界线提供了方法。Minimum Initial Specification 说明小型公共规则如何为本地决定保留空间;Running-Code Primacy 要求把规范发布与代码采用分开;On Reality Layers 则拒绝把标签、字节、字符、字形和人的反应压成同一事实。
RFC 1468 没有替代这些层。它只是让层与层之间的接口足够清楚:名称选择规则,转义改变状态,行界限制传播,中继保存对象,端点执行解释。日文邮件得以穿过不懂日文的网络,正因为公共协调没有冒充最终意义。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
