根据维基百科UTF-8页面,我从人们那里听到了相互矛盾的观点。

它们是一样的,不是吗?有人能澄清一下吗?


当前回答

我已经检查了Gumbo的答案中的链接,我想在这里粘贴那些东西的一部分,以存在于Stack Overflow上。

"...有些人错误地认为Unicode只是一个16位的代码,每个字符占用16位,因此有65,536个可能的字符。实际上,这是不对的。这是关于Unicode最常见的误解,所以如果你这样想,不要难过。

事实上,Unicode有一种不同的思考字符的方式,你必须理解Unicode思考事物的方式,否则就没有意义了。

到目前为止,我们假设一个字母映射到一些你可以存储在磁盘或内存中的位:

A -> 0100 0001

在Unicode中,字母映射到一个被称为码位的东西,这仍然只是一个理论概念。该代码点如何在内存或磁盘上表示则完全是另一回事……”

"...Unicode联盟给每个字母表中的每个柏拉图式的字母都分配了一个神奇的数字,写起来是这样的:U+0639。这个神奇的数字被称为码位。U+表示“Unicode”,数字是十六进制的。U+0639是阿拉伯字母Ain。英文字母A就是U+0041....”

"...假设我们有一个字符串

你好

在Unicode中,对应以下五个编码点:

U+0048 U+0065 U+ 006c U+ 006c U+ 006f。

只是一堆代码点。数字,真的。我们还没有说过如何将其存储在内存中或在电子邮件中表示它……”

"...这就是编码的作用。

Unicode编码最早的想法,导致了关于两个字节的神话,嘿,让我们把这些数字分别存储在两个字节中。所以Hello变成了

00 48 00 65 00 6c 00 6c 00 6f

对吧?别这么快!难道不可能是:

48 00 65 00 6c 00 6c 00 6f 00 ?……”

其他回答

UTF-8是Unicode文本的一种可能的编码方案。

Unicode是一个范围广泛的标准,它定义了超过140,000个字符,并为每个字符分配一个数字代码(一个码位)。它还定义了如何对文本进行排序、规范化、更改大小写等规则。Unicode中的字符由一个从0到0x10FFFF(包括0x10FFFF)的码位表示,但有些码位是保留的,不能用于字符。

将一串Unicode码位编码成二进制流的方法不止一种。这些被称为“编码”。最直接的编码是UTF-32,它将每个代码点存储为32位整数,每个整数宽为4字节。因为代码点最多只能到0x10FFFF(需要21位),所以这种编码有点浪费。

UTF-8是另一种编码,由于与UTF-32和其他编码相比有许多优点,它正在成为事实上的标准。UTF-8将每个码位编码为1、2、3或4个字节值的序列。ASCII范围内的码位被编码为一个单字节值,以便与ASCII兼容。超出这个范围的代码点分别使用2、3或4个字节,这取决于它们所在的范围。

UTF-8在设计时考虑了这些属性:

ASCII characters are encoded exactly as they are in ASCII, such that an ASCII string is also a valid UTF-8 string representing the same characters. More efficient: Text strings in UTF-8 almost always occupy less space than the same strings in either UTF-32 or UTF-16, with just a few exceptions. Binary sorting: Sorting UTF-8 strings using a binary sort will still result in all code points being sorted in numerical order. When a code point uses multiple bytes, none of those bytes contain values in the ASCII range, ensuring that no part of them could be mistaken for an ASCII character. This is also a security feature. UTF-8 can be easily validated, and distinguished from other character encodings by a validator. Text in other 8-bit or multi-byte encodings will very rarely also validate as UTF-8 due to the very specific structure of UTF-8. Random access: At any point in a UTF-8 string it is possible to tell if the byte at that position is the first byte of a character or not, and to find the start of the next or current character, without needing to scan forwards or backwards more than 3 bytes or to know how far into the string we started reading from.

如果我可以总结一下我从这篇文章中收集到的信息:

Unicode将字符分配给序数(十进制形式)。(这些数字被称为码位。)

à -> 224

UTF-8是一种将这些序数(十进制形式)“转换”为二进制表示的编码。

224 -> 11000011 10100000

注意,我们讨论的是224的二进制表示,而不是它的二进制形式,即0b11100000。

Unicode只是一个标准,它定义了一个字符集(UCS)和编码(UTF)来编码这个字符集。但一般来说,Unicode指的是字符集,而不是标准。

在5分钟内阅读每个软件开发人员绝对必须知道的关于Unicode和字符集(没有借口!)和Unicode的绝对最小值。

它们不是一回事——UTF-8是编码Unicode的一种特殊方式。

根据您的应用程序和您打算使用的数据,有许多不同的编码可供选择。据我所知,最常见的是UTF-8、UTF-16和UTF-32。

不幸的是,“Unicode”根据上下文以各种不同的方式使用。它最正确的用法(IMO)是作为编码字符集——即一组字符以及字符与表示它们的整数码位之间的映射。

UTF-8是一种字符编码——一种将字节序列转换为字符序列的方法,反之亦然。它涵盖了整个Unicode字符集。ASCII编码为每个字符一个字节,其他字符根据其确切的码位占用更多字节(当前定义的所有码位最多4个字节,即最多U-0010FFFF,实际上4个字节可以处理最多U-001FFFFF)。

当“Unicode”被用作字符编码的名称时(例如,作为. net编码。Unicode属性)通常表示UTF-16,它将大多数常见字符编码为两个字节。一些平台(特别是。net和Java)使用UTF-16作为它们的“原生”字符编码。如果您需要担心不能在单个UTF-16值中编码的字符(它们被编码为“代理对”),这将导致一些棘手的问题——但大多数开发人员从不担心这一点,IME。

关于Unicode的一些参考:

Unicode联盟网站,特别是教程部分 乔尔的文章 我自己的文章(面向. net)