注意:这是西方世界的观点,同时我们也有亚洲语言的历史和演变,我略过。在任何情况下,大多数字符集都转换为 Unicode
从历史上看,我们有 ASCII。实际上,我们还有其他字符编码,有些也没有区分大小写,但后来 ASCII 成为事实上的标准(在西方计算机上,我们使用拉丁脚本)。ASCII 是不够的,所以有一些扩展:“代码页”,所以仍然每个字符都是 8 位的,但是可以选择要使用的字符集(以及要支持的语言)。
所有常用的现代操作系统都诞生于这样的时代。所以程序以这样的约定、文件系统、API、文本文件等开始。
但是互联网和交换文件越来越普遍,因此在斯德哥尔摩制作的文件在德国或美国并不完全可读。ISO对一些代码页(如Latin-1等)进行了标准化,这些代码页有ASCII+一些共同的字符,而一些部分根据编码的不同而不同。而 Windows 使用了 Latin-1 并填充了未分配的空间(你看到它被描述为“ANSI”)。但是亚洲文字也变得很重要(更好的计算机,所以我们可以为日常使用付出更多的字符,而不仅仅是用于排版)。
因此 Unicode(和 ISO)开始制定新的标准。每个字符一组,与所有最常见的字符集兼容(因此您可以转换为 Unicode,然后返回,而不会丢失信息:这确实有助于平滑转换)。并且这样的新字符集应该有 16 位代码点 [警告:这不再是真的,但在第一个 Unicode 版本中是这样的]。(为此,我们有很多组合字符,“韩统一”(将中文、日文和旧韩文字符合二为一),以及编码新韩文字符的特殊情况。
新语言采用了这样的版本,所以 16 位 Unicode 字符。
一些操作系统使用这些 16 位字符添加了新的 API(Microsoft Windows 与长名称一起在文件系统上以兼容的方式进行,因此旧计算机可以读取文件 [只是短名称,并且使用 8 位字符]) . 通过这种方式,您可以与旧程序兼容,但新程序可以(它们不是被迫)使用新的 Unicode。
旧语言和 Unix 等待着,为如何获得兼容和新的 Unicode 而苦苦挣扎。
这似乎是你的世界(如你的问题),如此早期的 1990 年代。
你猜怎么着?16 位是不够的。所以新的(现在已经旧的)Unicode 添加了平面和代理。代理项是保持分配的 16 位 Unicode 有效的技巧,但允许(通过使用代理项)将字符创建为 0x10FFFF。这也是 ISO 的不同之处,它允许 31 位代码点。
与此同时,UTF-8 也出现了,因此与 ASCII(以及\0
许多库/操作系统使用的字符串结尾)兼容,但允许所有新的 Unicode 字符。
一些更现代的语言开始实现 UTF-32(因此使用 32 位 Unicode),一些旧的适应(例如新的 API),一些只是保留代理,因此将“代码点”更改为“代码单元”。Python 是例外之一:旧语言转换为完整的 Unicode(现在在内部,它选择了最佳大小 8 位、16 位或 32 位),但是 Python 3 转换却非常痛苦(并且与旧代码不兼容) ,而 10 年后,许多库还没有准备好),所以我认为其他旧语言在尝试“升级”之前会三思而后行。
您的“问题”问题是要获得 16 位(或 32 位)字符,您需要一个标志日。每个人都应该在同一天更新每个程序和每个操作系统。因此,您应该检查过去的旧代码并进行调整。或者有两组库,实际上所有操作系统都分成两部分:使用旧字符,或者使用新字符。
就个人而言,我认为 Unix 方式是最好的一种,所以使用 UTF-8:保持 ASCII 兼容,并扩展。旧程序可以(透明地)处理 Unicode 字符,如果它们是在 Unicode 时代之前构建的(用于打印、存储、传输等,显然要获得字符的语义,它们需要能够识别 Unicode)。
由于代码单元(因此一个 Unicode 代码点有时需要两个 16 位代码单元)和组合字符(不要假设一个字形仅由一个代码点描述),以及变体选择器、表情符号变体/标签,等等,迭代和修改单个字符没有多大意义。而且我们不应该忘记,字体可能会根据各种“字符”设计一个字形。
因此,由于现有的程序和基础设施,对于所有语言来说,在全球范围内使用 UTF-32 太难了。现在 UTF-8 似乎占主导地位,我认为我们应该保留 UTF-8:所以人们将使用 Unicode 库,或者只是透明地处理字节序列(可能只是合并、模板等),也许是简单的搜索(对于 ASCII、否则必须对 Unicode 字符串进行规范化)。