当前位置: 代码迷 >> 综合 >> 话说 Unicode 和 WTF-8
  详细解决方案

话说 Unicode 和 WTF-8

热度:76   发布时间:2023-12-12 15:30:11.0

如果世界上只有英文一种语言,字符串问题会简单很多。可惜,我们不得不面对五花八门的语言。于是,Unicode 应运而生,它试图提供一个包罗万象的文字编码方案。

UCS-2 编码

然而 Unicode 仅仅是一个逻辑设想,如何在计算机内存中物理实现,还需要更进一步的方案。第一个编码方案称为 UCS-2,该方案用两个字节共计 16 bits 表示一个符号。这样的话,我们可以表示 65536 个符号。如此看来,该方案足够用了。

好大喜功的 Windows 系统率先使用了 UCS-2 编码作为操作系统的字符编码,在某种意义上也大大推动了 Unicode 的普及应用。

然而,UCS-2 编码方案,采用了两个字节表示一个字符,这与过去的 ASCII 编码不兼容。在 ASCII 编码中,英文符号用一个字节表示。但是,在 UCS-2 中,英文字符也得用两个字节表示。于是,微软的 Visual C++ 提供了两套字符方案,char 和 wchar。Windows API 的函数也提供了两个版本,一个是 ASCII 版本,另一个是 Unicode 版本。这种结果是很痛苦的,我几乎从来都不会用 Visiual C++ 去处理字符串算法。

我觉得 UCS-2 编码方案还是太草率了。一种新的技术,如果不考虑与旧体系的兼容性,可能会带来巨大的灾难。

UTF-16 编码

不幸的是,Unicode 继续沿着这条邪路越走越远。忽然觉得 65536 个符号空间可能不够用,所以决定牺牲一部分编码,规定 0xD8~0xDF 开头的编码,需要采用 4 个字节进行编码,这 4 个字节的有效编码位数为 20。这样牺牲了一部分编码,但是扩充了 2^10 个新的 4 字节编码。

既然能用编码的开头若干位区分一个字符的长度是 2 字节,还是 4 字节。这样的方法直接用来区分 1 字节还是 2 字节,如果该方法用来实现于 ASCII 编码的兼容目标,Unicode 的今天会非常完美。可惜了!

我记得 DOS 时代,中国推出的汉字国标编码,就是于 ASCII 编码兼容的一种方案。ASCII 用 0x00~0x7F 编码表示,这与传统 ASCII 编码完全一致。中文则在剩余编码中用两字节表示。现在看,在多国文字编码这件事情上,还是中国人更有远见。

在 Unix 下使用 UTF-16(或 UCS-2、UCS-4) 会导致非常严重的问题。 用这些编码的字符串会包含一些特殊的字符,比如 '' 或 '/', 它们在文件名和其他 C 库函数参数里都有特别的含义。另外,大多数使用 ASCII 文件的 UNIX 下的工具,如果不进行重大修改是无法读取 16 位的字符的。基于这些原因,在文件名、文本文件、环境变量等地方,UTF-16(UCS-2、UCS-4等)不适合作为 Unicode 的外部编码。

UTF-8 编码

最后,发明 Unicode 的大佬们终于明白过来了,需要学习中国的国标编码,搞一个与 ASCII 兼容的编码才行。于是乎 ,UTF-8 终于出场了。

然而 UTF-8 有一个小问题,就是 UTF-16 中有一部分编码用来组成 4 字节编码。这 4 个字节的编码对于前后字节的内容是有规定的,也就是说,存在不少的 4 字节编码是非法编码。

WTF-8 编码

我们可不愿意费很大的劲判断四字节编码是否合法,于是,我们认为所有的编码都是合理的,这样就得到了UTF-8 的一个扩展编码集合——WTF-8,我不管你是如何编码的,照单全收。

  相关解决方案