UTF-8, UTF-16, and UTF-32

646

UTF-8、UTF-16和UTF-32有什么区别?

我理解它们都可以存储Unicode,并且每种编码使用不同数量的字节来表示字符。是否有选择一种编码比另一种更具优势的情况呢?


70
如果您对Unicode的工作原理感兴趣,请观看这个视频:http://www.youtube.com/watch?v=MijmeoH9LT4。 - user60456
1
这个视频专注于UTF-8,它很好地解释了可变长度编码的工作原理,并且大多数情况下与只读或只写固定长度ASCII的计算机兼容。Unicode的设计者在设计UTF-8编码时非常聪明。 - mins
2
UTF-8是大多数现代软件中保存文件的事实标准。更具体地说,它是HTML、配置和翻译文件(例如Minecraft)中最广泛使用的编码方式(因为Minecraft不接受任何其他编码方式来处理其所有文本信息)。UTF-32对于内部存储器表示来说速度很快,而UTF-16则有点过时,目前仅在Win32中出于历史原因使用(当Windows 95还存在时,UTF-16是固定长度的)。 - Kotauskas
2
@VladislavToncharov,UTF-16从来都不是一个固定长度的编码。你可能把它和UCS-2混淆了。 - user3160514
@Kotauskas JavaScript现在几乎所有的东西都还是使用UTF-16。 - Radvylf Programs
@user60456 - 我点击了链接,看到了Tom Scott,甚至在观看视频之前就自动点赞了你的评论,因为Tom太棒了,有传达信息的天赋。谢谢你分享这个链接。 - GroggyOtter
14个回答

6

根据你的开发环境,你可能没有选择字符串数据类型内部使用的编码方式。

但是,如果有选择的话,我建议在存储和交换数据时始终使用UTF-8。如果你的数据主要是ASCII数据,这将为你提供传输最少量的数据,同时仍能够编码所有内容。在现代计算机上,优化I/O最小化是正确的方法。


1
可以说,比空间要求更重要的是UTF-8具有免疫字节序的特性。UTF-16和UTF-32不可避免地会遇到字节序问题,而UTF-8只是一个八位字节流。 - IInspectable

2

阅读完答案后,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秒 - 大小250,000,000

UTF-32 -- 耗时3.143秒 - 大小125,030,570

ASCII -- 耗时2.362秒 - 大小500,000,000

UTF-32 -- MIC DROP


有没有想法是什么让Unicode变得如此快速? - undefined

2
如上所述,差异主要在于底层变量的大小,每种情况下这些变量会变得更大,以允许表示更多字符。
然而,字体、编码和其他方面都异常复杂(是否过度?),因此需要一个大链接来了解更多细节。

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

不要指望完全理解它,但如果您不想以后遇到问题,尽可能早地学习尽可能多的知识是值得的(或者让别人为您解决)。
保罗。

或者只需使用UTF-8作为默认编码,因为它已成为事实上的标准,并查看新系统是否支持它。如果不支持,您可以回到这篇文章。 - robotik
@paul-w-homer,你的链接已经失效了。 - Uncle Iroh

-2
简而言之,使用UTF-16或UTF-32的唯一原因是分别支持非英语和古代文字。
我想知道为什么会有人选择非UTF-8编码,因为显然对于web/编程目的来说它更高效。
一个常见的误解-后缀数字并不表示其功能。它们都支持完整的Unicode,只是UTF-8可以用单个字节处理ASCII,因此对于CPU和互联网来说更高效/不容易出错。
一些好的阅读材料:http://www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.htmlhttp://utf8everywhere.org

我不确定为什么你建议使用UTF-16或UTF-32来支持非英文文本。UTF-8可以很好地处理这个问题。而且,英文文本中也有非ASCII字符,比如零宽度不连字符或破折号。恐怕这个答案并没有太多价值。 - IInspectable
这个问题可能会被投票降低,因为即使在UTF-8中大多数字符是3字节字符,但UTF-8仍然常用于HTML文件。 - Ṃųỻịgǻňạcểơửṩ
@IInspectable支持并不是最佳措辞,推广或更好的支持将更为准确。 - robotik
在 Stack Overflow 的回答中,我不会发送像 http://utf8everywhere.org 这样的页面。 - DexterHaxxor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接