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

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


当前回答

作为一个直截了当的简单回答:

Unicode是一种表示多种人类语言字符的标准。 UTF-8是一种编码Unicode字符的方法。


是的:我故意忽略了UTF-8的内部工作原理。

其他回答

它们不是一回事——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)

它们是一样的,不是吗?

不,他们不是。


我认为你引用的维基百科页面的第一句话给出了一个很好的,简短的总结:

UTF-8是一种可变宽度字符编码,能够使用一到四个8位字节编码Unicode中的所有1,112,064个有效代码点。

阐述:

Unicode is a standard, which defines a map from characters to numbers, the so-called code points, (like in the example below). For the full mapping, you can have a look here. ! -> U+0021 (21), " -> U+0022 (22), \# -> U+0023 (23) UTF-8 is one of the ways to encode these code points in a form a computer can understand, aka bits. In other words, it's a way/algorithm to convert each of those code points to a sequence of bits or convert a sequence of bits to the equivalent code points. Note that there are a lot of alternative encodings for Unicode.


乔尔给出了一个非常好的解释,并概述了这里的历史。

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.

你通常从谷歌开始,然后想尝试不同的东西。 但是如何打印和转换所有这些字符集呢?

这里我列出了一些有用的一行程序。

Powershell:

# Print character with the Unicode point (U+<hexcode>) using this: 
[char]0x2550

# With Python installed, you can print the unicode character from U+xxxx with:
python -c 'print(u"\u2585")'

如果你有更多的Powershell trix或快捷方式,请评论。

在Bash中,你会喜欢libiconv和util-linux包中的iconv、hexdump和xxd(可能在其他*nix发行版中命名不同)。

# To print the 3-byte hex code for a Unicode character:
printf "\\\x%s" $(printf '═'|xxd -p -c1 -u)
#\xE2\x95\x90

# To print the Unicode character represented by hex string:
printf '\xE2\x96\x85'
#▅

# To convert from UTF-16LE to Unicode
echo -en "════"| iconv -f UTF-16LE -t UNICODEFFFE

# To convert a string into hex: 
echo -en '═�'| xxd -g 1
#00000000: e2 95 90 ef bf bd

# To convert a string into binary:
echo -en '═�\n'| xxd -b
#00000000: 11100010 10010101 10010000 11101111 10111111 10111101  ......
#00000006: 00001010

# To convert a binary string into hex:
printf  '%x\n' "$((2#111000111000000110000010))"
#e38182