UTF-8、UTF-16和UTF-32之间有什么区别?
我知道它们都将存储Unicode,并且每个都使用不同的字节数来表示一个字符。选择一个比另一个有优势吗?
UTF-8、UTF-16和UTF-32之间有什么区别?
我知道它们都将存储Unicode,并且每个都使用不同的字节数来表示一个字符。选择一个比另一个有优势吗?
当前回答
简而言之:
UTF-8: Variable-width encoding, backwards compatible with ASCII. ASCII characters (U+0000 to U+007F) take 1 byte, code points U+0080 to U+07FF take 2 bytes, code points U+0800 to U+FFFF take 3 bytes, code points U+10000 to U+10FFFF take 4 bytes. Good for English text, not so good for Asian text. UTF-16: Variable-width encoding. Code points U+0000 to U+FFFF take 2 bytes, code points U+10000 to U+10FFFF take 4 bytes. Bad for English text, good for Asian text. UTF-32: Fixed-width encoding. All code points take four bytes. An enormous memory hog, but fast to operate on. Rarely used.
长:参见维基百科:UTF-8, UTF-16和UTF-32。
其他回答
在阅读完答案后,UTF-32需要一些爱。
C#:
Data1 = RandomNumberGenerator.GetBytes(500_000_000);
sw = Stopwatch.StartNew();
int l = Encoding.UTF8.GetString(Data1).Length;
sw.Stop();
Console.WriteLine($"UTF-8: Elapsed - {sw.ElapsedMilliseconds * .001:0.000s} Size - {l:###,###,###}");
sw = Stopwatch.StartNew();
l = Encoding.Unicode.GetString(Data1).Length;
sw.Stop();
Console.WriteLine($"Unicode: Elapsed - {sw.ElapsedMilliseconds * .001:0.000s} Size - {l:###,###,###}");
sw = Stopwatch.StartNew();
l = Encoding.UTF32.GetString(Data1).Length;
sw.Stop();
Console.WriteLine($"UTF-32: Elapsed - {sw.ElapsedMilliseconds * .001:0.000s} Size - {l:###,###,###}");
sw = Stopwatch.StartNew();
l = Encoding.ASCII.GetString(Data1).Length;
sw.Stop();
Console.WriteLine($"ASCII: Elapsed - {sw.ElapsedMilliseconds * .001:0.000s} Size - {l:###,###,###}");
UTF-8—经过9.939秒-大小473,752,800
Unicode—消失0.853秒-大小2.5亿
UTF-32—消失3.143秒-大小125,030,570
ASCII—经过2.362秒-大小500,000,000
Utf-32——丢麦克风
UTF-8在ASCII字符代表文本块中的大部分字符的情况下具有优势,因为UTF-8将这些字符编码为8位(像ASCII一样)。它的另一个优点是只包含ASCII字符的UTF-8文件具有与ASCII文件相同的编码。
在ASCII不占主导地位的情况下,UTF-16更好,因为它主要每个字符使用2个字节。UTF-8将开始对高阶字符使用3个或更多字节,而UTF-16对大多数字符仅使用2个字节。
UTF-32将在4字节内涵盖所有可能的字符。这使得它非常臃肿。我想不出使用它有什么好处。
UTF-8为变量1 ~ 4字节。 UTF-16是可变的2或4字节。 UTF-32是固定的4字节。
在UTF-32中,所有字符都用32位编码。这样做的好处是可以很容易地计算字符串的长度。缺点是对于每个ASCII字符,您会浪费额外的3个字节。
在UTF-8字符有可变长度,ASCII字符编码为一个字节(8位),大多数西方特殊字符编码为两个字节或三个字节(例如€是三个字节),更奇特的字符可以占用四个字节。明显的缺点是,先验你不能计算字符串的长度。但与UTF-32相比,编码拉丁(英语)字母文本所需的字节要少得多。
UTF-16也是可变长度的。字符编码为两个字节或四个字节。我真的不明白这有什么意义。它有可变长度的缺点,但没有像UTF-8那样节省空间的优点。
在这三种语言中,UTF-8显然是传播最广泛的。
Unicode定义了一个巨大的字符集,为每个图形符号分配一个唯一的整数值(这是一个主要的简化,实际上不是真的,但对于这个问题的目的来说已经足够接近了)。UTF-8/16/32只是编码的不同方式。
简而言之,UTF-32对每个字符使用32位值。这允许他们对每个字符使用固定宽度的代码。
UTF-16默认使用16位,但这只提供了65k个可能的字符,这远远不够完整的Unicode集。所以有些字符使用一对16位的值。
UTF-8默认使用8位值,这意味着前127个值是固定宽度的单字节字符(最高位用于表示这是多字节序列的开始,为实际的字符值留出7位)。所有其他字符编码为最多4个字节的序列(如果内存可用的话)。
这就引出了它的优点。任何ascii字符都与UTF-8直接兼容,因此对于升级遗留应用程序,UTF-8是一个常见而明显的选择。在几乎所有情况下,它也将使用最少的内存。另一方面,你不能保证字符的宽度。它可能是1、2、3或4个字符宽,这使得字符串操作困难。
UTF-32则相反,它使用最多的内存(每个字符都是固定的4字节宽),但另一方面,您知道每个字符都有这个精确的长度,因此字符串操作变得简单得多。您可以简单地根据字符串的字节长度计算字符串中的字符数。你不能用UTF-8这样做。
UTF-16是一种折衷。它让大多数字符适合固定宽度的16位值。所以只要你没有中文符号、音符或其他东西,你可以假设每个字符是16位宽。它比UTF-32使用更少的内存。但在某种程度上,这是“两败俱伤”。它几乎总是比UTF-8使用更多的内存,而且它仍然无法避免困扰UTF-8(变长字符)的问题。
最后,只使用平台支持的内容通常是有帮助的。Windows内部使用UTF-16,因此在Windows上,这是显而易见的选择。
Linux稍有不同,但它们通常使用UTF-8来处理所有与unicode兼容的内容。
简短的回答:所有三种编码都可以编码相同的字符集,但它们将每个字符表示为不同的字节序列。