为什么会有多种Unicode编码?


41

我认为Unicode旨在解决由于大多数先前尝试(ASCII等)中的地址空间较小(8位)而导致具有许多不同编码的整个问题。

为什么会有那么多Unicode编码?甚至是(基本上)同一版本的多个版本,例如UTF-8,UTF-16等。


11
UTF-8与UTF-16不同。一旦我们遇到其他带有类地行星的太阳系,这个清单就会增加。
setzamora 2011年

1
@Joset:我们已经有克林贡语。BMP上有大多数地球语言,但有少量溢出到平原1,2。如果目前的理论是正确的,并且银河系中只有42个有感知力的物种达到可以使用太空旅行的地步(因此允许首次接触),那么我们应该能够将所有语言的所有字符压缩为UNICODE(假设我们可以扩展从21到22位以允许64个平原)。如果我们想包括尚未实现太空飞行的原始物种,那甚至会留下10位的缓冲空间。
马丁·约克

7
@Kevin Hsu:UTF-7、8、16LE,16BE,32LE,32BE。因此,至少存在6种真实编码。UTF-9和UTF-18是愚人节。
MSalters 2011年

9
关于标准的好处是有很多标准
洪德(Homde)2011年

1
看看Spolsky对Unicode和编码的看法。
MPelletier

Answers:


29

因为人们不想在每个角色上花费21位。在所有现代系统上,这实质上意味着每个字符使用三个字节,这是人们习惯使用的字节数的三倍,因此他们根本不愿意采用Unicode。必须找到妥协:例如,UTF-8非常适合英语文本,因为根本不需要转换旧的ASCII文件,但是它对欧洲语言的用处不大,而对亚洲语言的用处不大。

因此,基本上,是的,我们可以定义单个通用编码以及单个通用字符表,但是市场不会接受它。


8
+1好答案。老实说,这是唯一能够真正回答这个问题的人。所有其他答案(或多或少)都是关于字节如何以所有不同的unicode编码进行布局的。
Jacek Prucia,2011年

从历史上看,这是一个简单的分歧问题。但是,除了UTF-8之外,我今天没有看到太多用处,尽管在理论上场景中UTF-16会占用更少的空间,但并不是很大,这是罕见的。您最想节省空间的地方是网站,但是网站上充满了HTML代码,这是迄今为止使用UTF-8最短的代码。例如,您可以用来Shift JIS使日文网站的大小小于UTF-8等效项,但这只能起作用,因为它是专门用于日文的字符集。
aaaaaaaaaaaaaa

2
也不是真的。由于压缩格式实际上仅用于传输和存储。在应用程序中,通常使用UCS-2或UCS-4,因为它们是固定宽度的,但每个字符占用2或4个字节。因此,应用程序愿意为使用的方便性而放弃空间。
马丁·约克

but it is less useful for European languages, and of little use for Asian languages–这是错误的。“有用”是指压缩吗?好了,然后UTF-8为欧洲语言提供更好的压缩,因为在每个文本中都有空格和标点符号,它们仅占用一个字节。
尼克·沃伦金

37

Unicode是一种21位字符编码,唯一地描述了“ CodePoints”,每个代码点均由a字形(图形表示)表示。

  • 16位用于标识平面中的代码点(大多数代码点位于平面0上)。
  • 5位识别平面。

支持的编码为:

  • UTF-8(使用8位值对每个点进行编码)
  • UTF-16(使用16位值对每个点进行编码)
  • UTF-32(使用32位值编码每个点)

但是无论解码时采用哪种编码方式,它们都都映射回具有相同含义的特定代码点(这就是为什么它很酷)。

UTF-8

这是可变大小的格式。其中每个代码点由1到4个字节表示。

UTF-16

这是可变大小的格式。“基本多语言平面”(BMP或平面0)上的代码点可以由1个单个16位值表示。其他平面上的代码点由代理对(2个16位值)表示。

UTF-32

这是固定大小的格式。所有代码点均由单个32位值表示。


2
我也喜欢这个答案。正在写一个类似的东西,但是这一点很清楚。我还要补充一点,因为ASCII字符串自动为UTF-8,所以UTF-8也很有用。

4
拜托,这是基本的多语言平面,而不是简单的语言。
JSBձոգչ2011年

3
这是一个很好的答案,但我认为它仍然引出一个问题,“为什么?”,尽管这个答案暗含触及了这个问题。详细说明:UTF-32是编码Unicode字符的一种更直接的方法(有人说会更容易),但是由于每个字符都占用4个字节,因此它也浪费了很多空间。UTF-8更加紧凑,并且与ASCII向后兼容,但是它不是常规的:一个字符可能需要1到4个字节来编码,这使得使用它变得更加困难。UTF-16是两者之间的一种混合方法,大多都有各自的优缺点。
mipadi

4
在内存使用情况(UTF-8最好,因为最常见的字符是单字节)和处理速度(UTF-32最好,因为所有字符都是相同的大小)之间进行权衡,允许进行某些优化并给出完美的内存中的32位对齐)。结果,网络协议和文件格式通常使用UTF-8(以节省带宽/存储空间),而脚本解释器和语言运行时可能更喜欢UTF-16或UTF-32。
tdammers

2
@Marcel:“ CodePoint”不是“ CodePoint” character(因为可以从多个“ CodePoints”构造一个字符)。不要混淆这两个术语。但是您是正确的“ CodePoints”不要引用字形。字形只是代码点的图形表示。细微但重要的区别。
马丁·约克

25

我认为分离这两个想法很有用:

  1. Unicode-从世界各地到代码点的字符映射。
  2. 编码-代码点到位模式(UTF-8,UTF-16等)的映射。

UTF-8,UTF-16和其他编码各有优缺点。最好向Wikipedia咨询。


@jfs:如果仍然会有十几种或更多种不同的编码,而这些编码仍然是完全不同的,为什么还要完全使用Unicode?全局映射本身有什么用?
马修·沙利

10
@Matthew Scharley:您看错了。UNICODE将所有语言(包括Klingon)的所有字符映射到UNIQUE ID(代码点)。编码仅仅是将代码点压缩到磁盘或整个网络流上的一种方式。UTF代表“ UNICODE传输格式”。您应该始终将UNICODE码点视为21位值。与其他格式相比,优点是所有字符都可以唯一标识并且不会重叠(与Latin-1,Latin-2等不同)。
马丁·约克

@Matthew Scharley为什么要进行全局映射?实际上,每个人过去都有自己的映射(还记得代码页吗?)。我认为一个愚蠢的例子会清除一切。想象一下爱的想法。您将如何代表某人?送花吗 说我爱你”?每个人都有自己的表达方式。爱(这是一个抽象的想法)就像代码点。表达它就像编码。:)
jfs

4
Unicode是全局字母。UTF-x是计算机传输的方式,因为很难通过电线推纸。
梅尔(Mel)

1
@ Martin,Klingon实际上没有做到。腾尔金(Tengwar)或西里斯(Cirith)都没有写过托尔金的精灵舌头。
TRiG,2011年

9

UTF-7,UTF-8,UTF-16和UTF-32只是字符相同编码(代码点)的算法转换格式。它们是一种字符编码系统的编码。

与大多数用于处理大于256个字符的字符集的方案相比,它们在算法上也更易于向前和向后导航。

这与字形的一般国家/地区和特定于供应商的特定编纂有很大不同。仅在日语中,就有大量的JIS变体,更不用说EUC-JP和DOS / Windows机器所使用的JIS的面向代码页的转换,称为Shift-JIS。(在某种程度上,有这些算法的转换,但是它们并不是特别简单,并且可用的特定于供应商的字符存在差异。将其乘以数百个国家以及更复杂的字体系统的逐步演进(后绿屏)时代),而您却遇到了一场噩梦。

为什么需要这些Unicode转换形式?因为许多传统系统都假定使用ASCII范围的7位字符序列,所以您需要7位干净的解决方案来安全地通过这些系统传递未损坏的数据,因此您需要UTF-7。然后,出现了更多可以处理8位字符集的现代系统,但是null通常对它们具有特殊的含义,因此UTF-16不适用于它们。2个字节可以在第一个版本中对Unicode的整个基本多语言平面进行编码,因此对于要“从头开始理解Unicode”的系统(例如Windows NT和Java VM),UCS-2似乎是一种合理的方法。然后,除了这些扩展之外,还需要其他字符,从而实现了Unicode标准保留的21位编码的算法转换,从而诞生了代理对。这就需要UTF-16。如果您的某些应用程序中字符宽度的一致性比存储效率更重要,那么可以选择UTF-32(曾经称为UCS-4)。

UTF-16是唯一处理起来非常复杂的事情,并且很容易通过受此转换影响的小范围字符以及前导16位序列整齐地位于与末尾完全不同的范围来缓解这种情况16位序列。与尝试在许多东亚早期编码中向前和向后移动相比,这比以前要容易得多,在东亚编码中,您要么需要状态机(JIS和EUC)来处理转义序列,要么有可能向后移动几个字符直到找到可以保证的东西只能是前导字节(Shift-JIS)。UTF-16在可以有效切换16位序列的系统上也具有一些优势。

除非您不得不经历数十种(实际上是数百种)不同的编码,或者除非有时甚至在同一文档中(例如,旧版MacOs版本中的WorldScript)必须构建支持不同编码的多种语言的系统,否则您可能会认为Unicode转换格式是不必要的复杂性。但这比以前的替代方案大大降低了复杂性,每种格式都解决了真正的技术限制。它们之间也确实可以高效转换,不需要复杂的查找表。


1
各种JIS和EUC状态机确实很讨厌,而且如果您要在它们之间进行转换,则更是如此。Unicode极大地简化了这一过程。使用Unicode的唯一的主要问题是,你给个字节的停止思考的字符,你ASCII-使用小字符设置好的沙文主义你!
Donal Fellows,

6

Unicode并非旨在解决具有许多不同编码的整个问题。

Unicode旨在解决一个数字的整个问题,根据所使用的代码页,该数字代表许多不同的事物。0-127表示任何Ansi代码页中的相同字符。这就是所谓的ASCII图表或字符集。在允许256个字符的Ansi代码页中,数字128-255表示不同代码页中的不同字符。

例如

  • 数字$ 57代表所有代码页中的大写字母W,但
  • 数字$ EC表示代码页437(美国)中的无穷大符号,但是代码页775(波罗的海语)中的“带有CEDILLA的拉丁文小写字母N”
  • 美分符号在代码页437中为数字$ 9B,但在代码页775中为数字96

Unicode所做的就是把这一切颠倒了。在Unicode中,没有“重用”。每个数字代表一个唯一的字符。Unicode中的数字$ 00A2是百分号,而百分号在Unicode定义中没有其他位置。

为什么会有那么多Unicode编码?甚至是(基本上)同一版本的多个版本,例如UTF-8,UTF-16等。

没有相同编码的多个版本。同一Unicode字符定义图有多种编码,并且已经“发明”了这些编码,以管理Unicode中存在的各种语言平面的不同用法的存储要求。

Unicode定义(或具有定义的空间)4.294.967.295唯一字符。如果要在不进行任何算法转换的情况下将它们映射到磁盘/内存存储,则每个字符需要4个字节。如果您需要存储带有来自所有语言平面的字符的文本,则可能需要UTF-32(基本上是1个直字符-Unicode定义的4字节存储编码)。

但是几乎没有任何文本使用所有语言层面的字符。然后,每个字符使用4个字节似乎很浪费。尤其是考虑到地球上大多数语言是在所谓的基本多语言平面(BMP)中定义的:Unicode定义的前65536个数字。

这就是UTF-16出现的地方。如果您仅使用BMP中的字符,则UTF-16将非常高效地使用每个字符使用两个字节来存储该字符。对于BMP之外的字符,它将仅使用更多字节。UTF-16LE(Little Endian)和UTF-16BE(Big Endian)之间的区别实际上仅与计算机内存中数字的表示方式有关(字节模式A0表示十六进制$ A0或$ 0A)。

如果您的文本使用更少的不同字符(如西欧语言中的大多数文本),您将希望更多地限制文本的存储要求。因此,UTF-8使用单个字节存储ASCII图表中出现的字符(前128个数字),并选择Ansi字符中的一个字符(各个代码页的后128个数字)。对于此“最常用的字符”集以外的字符,它将仅使用更多字节。

总结一下:

  • Unicode是地球上所有语言中的字符(某些Klingon需要引导)然后又是某些字符(数学,音乐等)映射到唯一编号的映射。
  • 编码是一种算法,定义为使用给定文本中字符的“平均使用量”,使用此唯一字符映射表的编号尽可能有效地存储文本。

2
“数字0-127在任何代码页中表示相同的字符。” -好吧,除非您在谈论EBCDIC,否则这种情况$57就不是W
MSalters 2011年

@MSalters:你绝对正确。EBCDIC不同(还有其他EBCDIC)。我猜想我的大型机时代已经过去很久了,以至于我不记得了,或者我对这些记忆的压抑太久了……:-)
Marjan Venema

“数字0-127在任何代码页中表示相同的字符。” 实际上有一些编码,例如BinarySignWriting,它不是ASCII的超集。实际上,BinarySignWriting根本不包含任何ASCII字符。
TRiG 2011年

@TRiG:这就是为什么我编辑我的声明专门针对Ansi代码页的原因。在刷新之前一定已经做到了……
Marjan Venema

是。我写评论时有一个额外的评论和一个帖子更新。尽管如此,BinarySignWriting还是很有趣。
TRiG,2011年

2

Unicode定义了数字和字符之间的映射。但是,当您将数字发送给接收方时,仍然需要定义如何表示该数字。这就是UTF的目的。它定义了如何在字节流中表示数字。


2

UTF-32的基本原理很简单:它是Unicode代码点的最直接表示。那么,为什么不是UTF-32中的所有内容呢?两个主要原因:

一种是尺寸。UTF-32每个字符需要4个字节。对于在基本多语言位置中仅使用字符的文本,此空间是UTF-16的两倍。对于英文文本,它的空间是US-ASCII的4倍。

更大的原因是向后兼容。除“未编码” UTF-32之外,每种Unicode编码都是为了向后兼容以前的标准而设计的。

  • UTF-8:向后兼容US-ASCII。
  • UTF-16:向后兼容UCS-2(在扩展到BMP之前为16位Unicode)。
  • UTF-7:与非8位纯净邮件服务器的向后兼容性。
  • GB18030:向后兼容中文GB2312和GBK编码。
  • UTF-EBCDIC:向后兼容EBCDIC的基本拉丁语子集。

我认为Unicode旨在解决具有许多不同编码的整个问题

是的,的确如此。在UTF-8,-16和-32之间进行转换要比处理旧版本的数百种针对不同语言和操作系统的不同字符编码要容易得多。


1

您知道zip文件可以将文件压缩为更小的文件(尤其是文本文件),然后将其解压缩为原始文件的相同副本。

压缩算法实际上有几种具有不同特征的不同算法可供选择:存储(无压缩),压缩,精简(方法1-4),内含,标记化,放气,Deflate64,BZIP2,LZMA(EFS),WavPack,PPMd,从理论上讲,它可以尝试所有方法并选择最佳结果,但通常只使用Deflated。

UTF的工作方式大致相同。有几种编码算法各有不同的特性,但是您通常只选择UTF-8是因为它得到了广泛的支持,而不是其他UTF变体,这又是因为它与7位ASCII按位兼容,因此很容易在大多数通常使用8位ASCII扩展名的现代计算机平台上使用。


ørn:与zip文件的区别在于,有一个标头告诉您正在进行什么压缩。对于文本文件,我们仍然需要猜测不是吗?
马修·沙利

有一个特殊的序列可以准确地说明这一点。由于与ASCII的向后兼容性,它是可选的。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.