Unicode 补完计画,后日谈

Unicode補完計畫(Unicode-at-on,簡稱UAO,官方網站使用的識別系統用字是Unicode補完計画)是台灣電腦使用者針對大五碼(Big-5)延伸的紊亂、以及微軟Code Page 950(Microsoft Windows內建的Big-5轉碼表)未收錄某些常用字(又稱缺字問題)以及缺乏對於倚天中文系統、中國海字集延伸中的簡體中文、日文假名與日文漢字支援等問題所採取的其中一種解決方案(參看大五碼#影響)。透過對Code Page 950的修改,使得原始採用簡體中文或日語的內容,在複製至ANSI架構的程式時能轉換為Unicode補完計畫字集下的對應字元,而不會造成缺字的問題(詳細字元請參看字元的來源)。它是一個自由軟體。

可能很多大陆人都完全没有听说过这个东西,看我输入的是简体字,正常情况下我也应该不知道这个东西才对。不过现在网络这么发达,还是经常能和台湾人聊天的。偶然的机会让我知道了在非 Unicode 编码之中,还有非官方扩展这么神奇的东西。

最近遇到了一位大陆人,因为下载的文件使用的是 Unicode 补完计画的编码,导致无法正常读取。于是让我有理由来研究一下十几年前的前辈们是如何折腾 Windows 系统的。

首先 Unicode補完計畫 官方网站 已经挂了,虽然有个 Google Drive 的镜像站在顶着,但是大部分资料和下载都无法使用了。于是从某个镜像站下载到了最终版本:2.50alpha 的安装文件。

据说在 Windows 10 x64 下通过修改系统文件权限和 XP 兼容模式可以正确执行安装文件,但是我没有这个兴趣,所以直接解包,得到了最重要的文件:c_950.NLS

NLS 文件格式

接下来需要搞清楚 NLS 的文件格式,这方面只找到一个毛子写的文章,不但是蹩脚的英文,而且只针对毛子文这种只有 127 个字符的语言,对这边完全没有作用。

突破点出现在 c_932.NLS,也就是 Shift-JIS 的编码映射表。c_932.NLS 独特的文件大小吸引了我的注意。

BIG-5,GB2312,Shift-JIS 等都是兼容 ASCII 的编码,前 127 个编码和 ASCII 一样,而如果第一个字节超出 127,就表示需要使用两个字节来储存一个字符。不过实际上,各个编码对于第一个字节,也就是 lead byte,有更准确的定义,NLS 文件中,就只包含以各个 lead byte 开头的部分的映射,节约了空间。

所以 c_932.NLS 有两段不连续的 lead byte 定义,导致了较小的文件大小,让我能够推测出 NLS 文件的结构。

NLS 文件分为 文件头MultiByte to Unicode 映射表Unicode to MutliByte 映射表 三部分。因为我只需要研究从 Unicode 补完计划到 Unicode 的映射,因此忽略第三部分。

总之结果就是这个:读取 NLS 文件的 .NET Framework 的 Encoding

顺便一提,.NET Framework 本身并不依赖系统的 NLS 文件,而是在 mscorlib 中自带了编码表,所以 Unicode 补完计划对 .NET Framework 的程序应该没有效果吧。

转换程序

顺便还做出了转换程序,比起网络上流传的各种转换程序,我这个还有个独家功能:可以使用各种各样的 NLS 文件。如果你给出的是 c_932.NLS 的话,程序就可以正确地把 Shift-JIS 编码的文件转换到 Unicode。至于其它的则没有测试过。

本体: MultiByteToUnicode.exe

c_950.NLS: c_950.nls

最简单的使用方式是将下载到的两个文件放在一起,然后将 Unicode 补完计划编码的文件拖动到 MultiByteToUnicode.exe 上。转换后的文件会在文件名里加上 .utf-16 这样的标识。也可以通过命令行,给出输入文件,使用的 NLS 文件,和输出文件的地址。