2KB项目,专业的源码交易网站 帮助 收藏 每日签到

UCS 和 UTF-8 编码

  • 时间:2019-01-23 18:37 编辑:2KB 来源:2KB.COM 阅读:362
  • 扫一扫,手机访问
  • 分享
摘要: 英文原文:UCS
英文原文:UCS vs UTF-8 as Internal String Encoding

Unicode混乱地有点眼花缭乱。它在很多方面有点让人迷失,但最有趣的也正是为让它良好工作时所带来的复杂性。尽管Unicode协会积极发展着Unicode标准,但使用Unicode时很容易让人遗忘它背后丰富多彩的历史。除了众所周知的Unicode,还有ISO 10646中定义的通用字符集。

如今的Unicode以及ISO的UCS最实用的目的是做相同的事情但却有一个稍微有差别的名字。但一直以来并非总是这样的,刚开始时它们的目的是不同的。原因或许是因为有关联信息,或者是因为某些方面在历史上闪耀过。

在这里我就不详谈Unicode的历史了,因为已经有很多人谈过了。如果你感到好奇,可以从以下链接里面了解一下:

需要提出的是,为了明白字符集在某些特定情况下的行为,我们要知道一些相关的基础知识。目前 Unicode 和 ISO 10646 还不是同一个东西,他们有各自独特的规则。比如说,各种编码的命名方式就不一样。  UCS2和UCS4分别是通用字符集(UCS)中代表2字节和4字节编码。UTF格式是后来才制订的,现在UTF仍然代表着Unicode转换格式(Unicode Transformation Format),也代表UCS转换格式(UCS Transformation Format)。

UTF家族

一开始的时候,Unicode是16位编码的,大致相同于UCS2编码(已过时)。 渐渐地Unicode支持的字符越来越多,远远超过16位,固定长度编码就不太适用了。

ISO工作组很早就开发了一个编码标准,用来映射ASCII兼容的字符,也就是UTF-1。但是这个标准有很多严重问题,例如不能确保自己的统一性(lack of self synchronization)。如果你接收到一个可能被截断或者损坏的字符流,你可能完全不能正确解释这个字符串,除非你知道全部(包括截断前)的正确字符串。

1992年,UTF-8 问世(比Unicode 2.0正式面世早几年)。现在 UTF-8 应该是数据交换中使用最多的字符编码。使用 UTF-8 的网站占据了大约 因特网的 80%.  大概是因为 UTF-8 不仅十分实用,也很可靠。

当单元固定长度16位的UCS-2到达容量上限不能支持更多的 Unicode 字符的时候,Unicode协会放弃了UCS-2。这就导致了两件事情的发生:他们必须引入16位的变长编码;同时必须减少编码点(code point)总数,使得UTF-16在特性上与UTF-8兼容。也就是说,如果一个字符流已损坏(或已被截断),你也能接收到(除了截断点外后面的)大部分正确的数据。比如说,如果一个字符不能使用一个16位编码单元来表示,还需要额外的编码单元(很正常,采用了变长编码),则必需保证一切正常运行。如果前面那个编码单元在传输过程中丢失了,剩下的那个编码单元实际上是一个非法字符,是可以被忽略的错误字符。而同一个流的后续字符并不受影响,能正确解释。

为了达到这个目的,他们使用了互补单元(surrogate pair)来编码长于16位的字符。实际上,单个UTF-16编码单元定义为2字节或者4字节长,不会有超过4字节的。这样的话,一个编码单元就可以储存 65536 个字符。超出这个范围的字符,就会使用2个编码单元,每个编码单元的数据都经过处理,使得彼此之间都是唯一的。如果单独对互补单元进行处理,那么将发现他们是不完整的字符。这个方法可行的关键是:前互补单元保留了DC00到DF00范围,后互补单元保留了D800到DBFF范围。这样导致的结果是UTF-16可表示的总字符个数是UTF家族中最少的。

UTF-32和之前的UCS-4编码一样,也是固定编码单元长度的。为什么UTF-32能保持固定长度?现在UTF-16是容量最小的UTF编码,它规定了编码点总数为 1112064,也就确定了 Unicode 或 ISO 10646所能定义的字符总数。既然 Unicode 现在只使用了 0 到 10FFFF 范围,UTF-32看起来是不是很鸡肋?拥有32位的编码单元长度,却只使用了21位,是不是有些浪费空间?

UTF-8的编码单元最多使用了31位,不会超过32位。所以UTF家族在最差情况下是一样的:

  UTF-8 UTF-16 UTF-32
最大编码点 10FFFF 10FFFF 10FFFF
编码单元长度 8 位
16 位 32 位
字节依赖 no yes yes
字符占用最少字节 1 2 4
字符占用最多字节 4 4 4

很多人以为UTF-8在最差情况下将占用超过4字节的空间,这其实是错的,至少目前是错的。因为 UTF-16 制订出来了,而且 Unicode 也没有收录超过 1112064 个字符。

选用哪个编码?

毫无疑问,UTF-8看起来是最好的编码。UTF-32显然不行,浪费了大约40%的空间。UTF-8不是字节依赖的,这也是个突出优点。另外,C语言中也可以使用UTF-8(也就是说它是向后兼容的)。在最差情况下,UTF-8占用的空间和其他UTF编码是一样的。

深入调查之后,根据具体语言的不同,UTF-16可能是更高效的储存编码。例如日本语,使用UTF-16会比UTF-8更高效。大部分日本语字符在使用UTF-16储存的时候,只需要使用一个编码单元(2字节);但是如果使用UTF-8的话,就需要占用3字节的空间。

但是如果日本文字夹杂到ASCII字符里,情况就不一样了。比如说,XML或HTML文档包含了大量嵌入的控制字符(基本上都是ASCII字符),这个时候使用UTF-8就高效很多了(非压缩的情况下)。日本语维基百科的首页使用UTF-8保存只需92KB,UTF-16的话则需要166KB。

当然,总的来说UTF-8应用范围很广。我很少看到UTF-16编码的文档,除了 Windows 用户使用记事本创建保存的文档之外基本没看到。

内部编码

但是当内部编码使用Unicode时问题就没那么简单的了,并且在这个问题上也有过不同的意见。

内部编码使用最广的是UTF-8和UTF-16。Java, C# and Objective C (以及Windows API),这些内部编码都是使用UTF-16。UTF-16 的好处是它允许你在基础平面内方便使用绝大多数的数据。这就意味着像strlen()这样的函数既要返回的字节数也要返回字符数。

在很长的时间内,并没有许多关于内部编码使用UTF-16的争论。很长时间内除了很多c程序,仅仅只有Perl语言使用UTF-8作为内部编码。但是现在Ruby,GO以及Rust已经开始使用UTF-8作为内部编码了。当然Ruby可以使用不同的字符编码,但是UTF-8是使用最广泛的一个。

统一访问的重要性

那 UTF-16 为什么这样流行?

一般人都认为,UTF-16最大的卖点是可以直接定位字符。如果全部编程语言都使用21位精度来表示完整的Unicode字符的话,这是没有问题的。不幸的是,C# 和 Java 都不支持。 Java 不支持直接使用UTF-16尚可原谅,因为它诞生得很早,字符串的表示方式也不一样。但 C#不支持UTF-16就说不过去了。

Rust 和 Go 对UTF-16的直接支持则要好得多。虽然它们都默认使用 UTF-8 编码来表示字符串,但是同时也提供了32位数据类型来表示 UTF-16 (Go 语言中的rune,rust中的char)。 在这两种语言中,你都可以遍历整个字符串中实际的Unicode字符。很多情况下,遍历操作足够了。例如说,文本分析通常只需要同时检查一个或者两个字符。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。


2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务

  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【计算机/互联网|】Nginx出现502错误(2020-01-20 21:02)
【计算机/互联网|】网站运营全智能软手V0.1版发布(2020-01-20 12:16)
【计算机/互联网|】淘宝这是怎么了?(2020-01-19 19:15)
【行业动态|】谷歌关闭小米智能摄像头,因为窃听器显示了陌生人家中的照片(2020-01-15 09:42)
【行业动态|】据报道谷歌新闻终止了数字杂志,退还主动订阅(2020-01-15 09:39)
【行业动态|】康佳将OLED电视带到美国与LG和索尼竞争(2020-01-15 09:38)
【行业动态|】2020年最佳AV接收机(2020-01-15 09:35)
【行业动态|】2020年最佳流媒体设备:Roku,Apple TV,Firebar,Chromecast等(2020-01-15 09:31)
【行业动态|】CES 2020预览:更多的流媒体服务和订阅即将到来(2020-01-08 21:41)
【行业动态|】从埃隆·马斯克到杰夫·贝佐斯,这30位人物定义了2010年代(2020-01-01 15:14)
联系我们

Q Q: 7090832

电话:400-0011-990

邮箱:7090832@qq.com

时间:9:00-23:00

联系客服
商家入住 服务咨询 投拆建议 联系客服
0577-67068160
手机版

扫一扫进手机版
返回顶部