18

如果您有一个要翻译成世界上每种语言的网站,因此有一个包含所有这些翻译的数据库,那么哪种字符编码最好?UTF-128?

如果是这样,所有浏览器都理解选择的编码吗?字符编码是直接实现还是存在隐藏因素?

提前致谢。

4

3 回答 3

37

如果您想为 Web 内容支持多种语言,则应使用涵盖整个 Unicode 范围的编码。用于此目的的最佳选择是 UTF-8。UTF-8 是 Web 的首选编码;来自HTML5 草案标准

鼓励作者使用 UTF-8。一致性检查器可能会建议作者不要使用遗留编码。[RFC3629]

创作工具应该默认为新创建的文档使用 UTF-8。[RFC3629]

UTF-8 和 Windows-1252 是浏览器需要支持的唯一编码,而 UTF-8 和 UTF-16 是 XML 解析器需要支持的唯一编码。因此,UTF-8 是所有东西都需要支持的唯一通用编码。


以下是对 Liv 答案的扩展回应,而不是单独的答案;它描述了为什么即使对于 CJK 内容,UTF-8 也比 UTF-16 更可取。

对于 ASCII 范围内的字符,UTF-8 比 UTF-16 更紧凑(1 字节 vs 2)。对于 ASCII 范围和 U+07FF 之间的字符(包括扩展拉丁文、西里尔文、希腊文、阿拉伯文和希伯来文),UTF-8 也使用每个字符两个字节,所以它是一个洗牌。对于基本多语言平面之外的字符,UTF-8 和 UTF-16 都使用每个字符 4 个字节,所以这是一个清洗。

UTF-16 比 UTF-8 更有效的唯一范围是用于从 U+07FF 到 U+FFFF 的字符,其中包括印度字母和 CJK。即使对于该范围内的大量文本,UTF-8 最终也具有可比性,因为该文本的标记(HTML、XML、RTF 或其他任何内容)都在 ASCII 范围内,而 UTF-8 是其中的一半UTF-16 的大小。

例如,如果我随机选择一个日文网页,即 nhk.or.jp 的主页,它是用 UTF-8 编码的。如果我将其转码为 UTF-16,它会增长到几乎是原始大小的两倍:

$ curl -o nhk.html 'http://www.nhk.or.jp/'
$ iconv -f UTF-8 -t UTF-16 nhk.html > nhk.16.html
$ ls -al nhk*
-rw-r--r-- 1 lambda lambda 32416 Mar 13 13:06 nhk.16.html
-rw-r--r-- 1 lambda lambda 18337 Mar 13 13:04 nhk.html

UTF-8 在几乎所有方面都比 UTF-16 好。它们都是可变宽度编码,因此具有一定的复杂性。然而,在 UTF-16 中,4 字节字符相当少见,因此更容易做出固定宽度假设并让一切正常工作,直到遇到你没有抓住的极端情况。这种混淆的一个例子可以在编码 CESU-8 中看到,如果您将 UTF-16 文本转换为 UTF-8,只需将代理对的每一半编码为一个单独的字符(每个字符使用 6 个字节; 三个字节以 UTF-8 编码代理对的每一半),而不是将代理对解码为其代码点并将其编码为 UTF-8。这种混淆很常见,以至于错误的编码实际上已经标准化,因此至少可以使损坏的程序进行互操作。

对于绝大多数内容而言,UTF-8 比 UTF-16 小得多,如果您担心大小,压缩文本总是比选择不同的编码更好。UTF-8 与使用以空字符结尾的字节序列来表示字符串的 API 和数据结构兼容,因此只要您的 API 和数据结构不关心编码或已经可以处理其字符串中的不同编码(例如与大多数 C 和 POSIX 字符串处理 API 一样),UTF-8 可以正常工作,而无需为宽字符提供一套全新的 API 和数据结构。UTF-16 没有指定字节序,所以它让你处理字节序问题;实际上存在三种不同的相关编码,UTF-16、UTF-16BE 和 UTF-16LE。UTF-16 可以是大端或小端,所以需要一个BOM来指定。UTF-16BE 和 LE 是 big endian 和 little endian 版本,没有 BOM,因此您需要使用带外方法(例如 Content-Type HTTP 标头)来指示您正在使用哪个,但是 out-带外标头因错误或丢失而臭名昭著。

UTF-16 基本上是一个意外,发生这种情况是因为人们最初认为 16 位足以编码所有 Unicode,因此开始更改其表示和 API 以使用宽(16 位)字符。当他们意识到他们需要更多字符时,他们想出了一个方案,使用一些保留字符来使用两个代码单元对 32 位值进行编码,因此他们仍然可以使用相同的数据结构进行新的编码。这带来了像 UTF-8 这样的可变宽度编码的所有缺点,而没有大多数优点。

于 2011-04-21T16:09:25.073 回答
13

UTF-8是 Unicode 的事实上的标准字符编码。

UTF-8 类似于 UTF-16 和 UTF-32,因为它可以表示 Unicode 字符集中的每个字符。但与 UTF-16 和 UTF-32 不同的是,它具有向后兼容 ASCII 的优点。它的优点是避免了字节序的复杂性以及由此产生的使用字节顺序标记 (BOM) 的需要。由于这些和其他原因,UTF-8 已成为万维网的主要字符编码,占所有网页的一半以上。

没有 UTF-128 这样的东西。

于 2011-04-20T15:44:13.640 回答
1

在处理这个问题时,您需要考虑更多。例如,您可以用 UTF-8 表示中文、日语和几乎所有内容——但它会为每个这样的“外来”字符使用一组转义字符——因此,您的数据表示可能会占用大量存储空间,因为这些额外的标记。您也可以查看 UTF-16,它不需要转义/标记,例如中文、日文等 - 但是,每个字符现在需要 2 个字节来表示;因此,如果您主要处理拉丁字符集,那么您只是将数据存储的大小增加了一倍,而没有任何好处。还有专门用于日语的 shift-jis,它比 UTF-8 或 UTF-16 更好地表示这些字符集,但是你不支持拉丁字符。我会说,如果您事先知道会有很多外来字符,请考虑使用 UTF-16;如果您主要处理重音符号和拉丁字符,请使用 UTF-8;如果您不使用任何拉丁字符,请考虑 shift-jis 等。

于 2011-04-20T15:49:38.707 回答