ISO 2022

来自GSXAB的知识库
ISO2022
术语名称 ISO2022
英语名称 ISO2022

ISO/IEC 2022 是一种兼容 ASCII 的多语言字符编码框架标准,是对多地区字符集应当遵循的共同规则及如何实现多地区字符集间动态切换的规范。 ISO 2022 是一种使用多个字符集的 7 或 8 位编码,设计上除可在 8 位字节环境中使用,也兼容 7 位字节的环境。 由于使用 ISO 2022 时需要根据控制序列切换字符集,使用 ISO 2022 标准时实际是将符合标准的不同字符集组合成一种有状态的字符编码方案。

ISO 2022 允许将符合其中规范的字符集同时使用,本质上是一种字符集之间的兼容方案。但也有几种遵循这一标准的编码被使用“ISO-2022-”开头称呼,如 ISO-2022-CN 。不过也不只有这几种以此法命名的标准符合 ISO 2022 对单个字符集的标准。

初版于 1971 年,是 ISO 与 IEC 的标准。后续被 ISO 10646 取代。

编码方式

一个能兼容 ISO 2022 的 8 位字符集应当仅包含 94 (0x21-0x7E)或 96 (0x20-0x7F)个字符。考虑到多字节编码的情况,也可以是 94 或 96 的幂。

ISO 2022 制定了一种双层的字符编码映射,但是在二进制数据和码位直接映射之前,是将二进制数据映射到某个编号的工作集(working set),并且需要根据当前状态确认这个工作集实际是哪种字符集。一种转义序列可以将字符集注册项中的某一个当前指定(designate)为工作集,或者说调用(invoke)某个字符集。

分区记号

ISO 2022 中可以切换的工作集一共有四个,分别称为 G0 到 G3 ,控制字符集有两个,即 C0 和 C1 。

编码解析方式

在最终编码中:

  • 控制字符范围
    • 三个固定码位总是解析成对应的字符,包括 0x1B ESC 0x20 SP 0x7F DEL
    • 其他的 0x00-1F 即 C0 区,解析成 C0 的对应字符,
    • 0x80-9F 即 C1 区,解析成 C1 的对应字符,
  • 图形字符范围(如果不考虑临时切换)
    • 0x21-7E 即 GL 区解析成 GL 区当前调用的工作集,如 G0 工作集的 0x21-0x7E
    • 0xA0-FF 即 GR 区解析成 GR 区当前调用的工作集,如 G0 工作集的 0x20-0x7F
  • 存在临时激活 G2 或 G3 的情况时
    • 单次换档区(由具体编码规定, GL 和 GR 中的一个)解析为对应临时激活工作集的 0x20-0x7F

注意:

  • 图形字符范围内由于空格和 DEL 是固定字符,在 GL 时比在 GR 时能使用的字符数少两个。
  • 如果当前二进制串是 7 位字节的环境,则不存在以上 C1 和 GR 所在的 0x80-0x90 ,只有 C0 和 GL ;且单次换档区也一定是 GL 。
  • 可以有多字节字符集,每个字节都是这 94 或 96 个,每个字节都这样处理。

转义序列

转换序列的格式是以 ESC 字符开头,随着一些可选的 0x20-2F 的操作数,结束在 0x30-0x7E 的最终参数上,本文只列出重要的转义序列。

切换转义序列

切换功能的转换序列关于如何切换当前 GL/GR 与 G0-G3 之间的调用关系。

字符序列 缩写 名称 指令含义
0x0F SI SI / LS0 移入;锁定换档 0 从现在起 GL 调用 G0
0x0E SO SO / LS1 移出;锁定换档 1 从现在起 GL 调用 G1
0x1B.6E ESC n LS2 锁定换档 2 从现在起 GL 调用 G0
0x1B.6F ESC o LS3 锁定换档 3 从现在起 GL 调用 G3
0x8E SS20x1B.4E ESC N SS2 单次换档 2 仅对下一个字符(看对应编码中一个字符的字节数)单次换档区调用 G2
0x8F SS30x1B.4F ESC O SS3 单次换档 3 仅对下一个字符(看对应编码中一个字符的字节数)单次换档区调用 G3
0x1B.7E ESC ~ LS1R 锁定换档 1 ,右侧 从现在起 GR 调用 G1
0x1B.7D ESC } LS2R 锁定换档 2 ,右侧 从现在起 GR 调用 G2
LS3R 锁定换档 3 ,右侧 从现在起 GR 调用 G3

装载转义序列

字符序列 缩写 名称 指令含义
0x1B.20.?? ESC SP ? ACS 声明编码结构 指定最后一个参数对应的编码功能。指包括位数、支持94/96位编码、使用哪些指令等功能。
0x1B.21.?? ESC ! ? CZD C0 指定 指定使用的 C0 控制字符集。
0x1B.22.?? ESC " ? C1D C1 指定 指定使用的 C1 控制字符集。
0x1B.24.28.?? ESC $ ( ? GZDM4 G0 指定多字节 94 字符集 指定使用的 G0 字符集。
0x1B.24.29.?? ESC $ ) ? G1DM4 G1 指定多字节 94 字符集 指定使用的 G1 字符集。
0x1B.24.2A.?? ESC $ * ? G2DM4 G2 指定多字节 94 字符集 指定使用的 G2 字符集。
0x1B.24.2B.?? ESC $ + ? G3DM4 G3 指定多字节 94 字符集 指定使用的 G3 字符集。
0x1B.24.2D.?? ESC $ - ? G1DM6 G1 指定多字节 96 字符集 指定使用的 G1 字符集。
0x1B.24.2E.?? ESC $ . ? G2DM4 G2 指定多字节 94 字符集 指定使用的 G2 字符集。
0x1B.24.2F.?? ESC $ / ? G3DM4 G3 指定多字节 94 字符集 指定使用的 G3 字符集。
0x1B.25.?? ESC % ? DOCS 指定其他编码方案系统 切换编码。
0x1B.26.?? ESC & ? IRR 指定注册版本 在指定序列前,指定字符集的具体版本。
0x1B.28.?? ESC ( ? GZD4 G0 指定单字节 94 字符集 指定使用的 G0 字符集。
0x1B.29.?? ESC ) ? G1D4 G1 指定单字节 94 字符集 指定使用的 G1 字符集。
0x1B.2A.?? ESC * ? G2D4 G2 指定单字节 94 字符集 指定使用的 G2 字符集。
0x1B.2B.?? ESC + ? G3D4 G3 指定单字节 94 字符集 指定使用的 G3 字符集。
0x1B.2D.?? ESC - ? G1D6 G1 指定单字节 96 字符集 指定使用的 G1 字符集。
0x1B.2E.?? ESC . ? G2D6 G2 指定单字节 96 字符集 指定使用的 G2 字符集。
0x1B.2F.?? ESC / ? G3D6 G3 指定单字节 96 字符集 指定使用的 G3 字符集。

ISO-2022-CN

RFC 文档 RFC 1922 于 1996 年给出了两个编码方案。该方案融合了 ASCII 、 GB 2312 以及台湾地区使用的 CNS 11643 。但是因为复杂度较高,这一编码除了在邮件等特殊场景(因为 SMTP 正文只支持 7 位字节)外几乎没有使用。

ISO-2022-CN 中,可分配以下四种字符集:

  • G0 : ASCII
  • G1 :通过 ESC $ ) A 绑定到 GB 2312-1980 ,通过 ESC $ ) G 绑定到 CNS 11643-1992 第一平面
  • G2 :通过 ESC $ * H 绑定到 CNS 11643-1992 第二平面

ISO-2022-CN-EXT 中,除上述字符集外,还可以分配以下字符集到工作集中:

  • G1 : 通过 ESC $ ) E 绑定到 ISO-IR-165 (GB 2312 的一个扩展修改版本)
  • G2 :通过 ESC $ + I 绑定到 CNS 11643-1992 第三平面,通过 ESC $ + J 绑定到 CNS 11643-1992 第四平面,通过 ESC $ + K 绑定到 CNS 11643-1992 第五平面,通过 ESC $ + L 绑定到 CNS 11643-1992 第六平面,通过 ESC $ + M 绑定到 CNS 11643-1992 第七平面

使用

ISO 2022 在中文中只用在邮件等只有 7 位字节的场景相关编码中,是极其少见的编码。

首先是效率问题。 带有指令的切换,在单语言场景下效率不高于不考虑切换的编码,即直接将 ASCII 外的第二种编码编入 0xA0-FF ,如 ISO 8859 、 GB 2312 的字符编码等;而在跨语言场景下,在 ASCII 与每种语言之间切换时都有额外字节,代价较大,并不实用。

而且有状态还使得二进制数据不能局部读取,缺少局部错误时的可恢复能力。

字符集覆盖较小,每种单独的标准中只能放置有限种类的字符集,且各自按各自的习惯编码;对多字节字符,连续的字节中总是同一工作集中的字节,实际编码空间中有大量未使用的区域。

可能是出于以上几点,这两个标准并没有广泛主流实现,提出后中文环境仍然以 GB 2312 为主并在几年后被 GB 18030 代替。


常见字符编码
早期编码 电报码、 BCD 码BCDICEBCDIC)、ASCIIISO 646
ISO 8859 ISO 8859-1 、 ISO 8859-2 、……
国标系列 IBM 代码页 936 / GB 2312IBM 代码页 1386 / GBKIBM 代码页 54936 / GB 18030
Unicode / ISO 10646 UTF-7 、 UTF-8UTF-16UTF-32