什么是Unicode,UTF

Unicode的基础是什么以及为什么需要UTF-8或UTF-16? 我在Google上研究过这些内容,也在这里搜索,但对我而言并不清楚。

在VSS进行文件比较时,有时会出现一条消息,说明两个文件的UTF不同。 为什么会这样呢?

请简单解释一下。


为什么我们需要Unicode?

在(不太)早期,所有存在的都是ASCII。 这是可以的,因为所有需要的都是几个控制字符,标点符号,数字和字母,就像这句话中的那些。 不幸的是,今天的全球互通和社交媒体的奇怪世界并没有预见到,在同一份文件中看到英文,العربية,汉语,古巴文,ελληνικά和ភាសាខ្not不是很少见(我希望我没有打破任何旧浏览器)。

但出于论点的缘故,可以说Joe Average是一名软件开发人员。 他坚持认为他只会需要英语,因此只想使用ASCII。 这对用户的Joe来说可能没问题,但这对软件开发人员Joe来说并不合适。 世界上大约有一半人使用非拉丁字符,使用ASCII对这些人来说可能是不合理的,最重要的是,他正在关闭他的软件,以适应一个庞大且不断增长的经济。

因此,需要包含所有语言的包含字符集。 因此出现了Unicode。 它为每个字符分配一个称为代码点的唯一编号。 Unicode相对于其他可能的集合的一个优点是前256个代码点与ISO-8859-1相同,因此也是ASCII。 另外,绝大多数常用字符仅由两个字节表示,称为基本多语言平面(Basic Multilingual Plane,BMP) 。 现在需要使用字符编码来访问该字符集,并且如问题所述,我将专注于UTF-8和UTF-16。

内存考虑

那么有多少字节可以访问这些编码中的字符?

  • UTF-8:
  • 1个字节:标准ASCII
  • 2字节:阿拉伯文,希伯来文,大部分欧洲文字(最明显的不包括格鲁吉亚文)
  • 3个字节:BMP
  • 4个字节:所有Unicode字符
  • UTF-16:
  • 2个字节:BMP
  • 4个字节:所有Unicode字符
  • 现在值得一提的是,不在BMP中的字符包括古老的脚本,数学符号,音乐符号以及较为罕见的中/日/韩(CJK)字符。

    如果您将主要使用ASCII字符,那么UTF-8肯定会提高内存效率。 但是,如果您主要使用非欧洲脚本,则使用UTF-8的内存效率可能会比UTF-16少1.5倍。 处理大量文本时(如大型网页或冗长的文档)可能会影响性能。

    编码基础

    注意:如果您知道UTF-8和UTF-16的编码方式,请跳至下一节以了解实际应用。

  • UTF-8:对于标准ASCII(0-127)字符,UTF-8代码是相同的。 如果需要现有ASCII文本的向后兼容性,这使UTF-8成为理想选择。 其他字符需要2-4个字节。 这是通过在每个字节中保留一些位来表示它是多字节字符的一部分来完成的。 特别是,每个字节的第一位是1以避免与ASCII字符冲突。
  • UTF-16:对于有效的BMP字符,UTF-16表示只是它的代码点。 但是,对于非BMP字符,UTF-16引入了代理对 。 在这种情况下,两个双字节部分的组合映射到非BMP字符。 这些双字节部分来自BMP数字范围,但由Unicode标准保证作为BMP字符无效。 另外,由于UTF-16以两个字节为基本单位,因此受到字节序的影响。 为了补偿,保留的字节顺序标记可以放置在表示字节顺序的数据流的开始。 因此,如果您正在阅读UTF-16输入,并且没有指定字节顺序,那么您必须检查这一点。
  • 可以看出,UTF-8和UTF-16远没有彼此兼容。 所以如果你正在做I / O,确保你知道你正在使用哪种编码! 有关这些编码的更多详细信息,请参阅UTF常见问题解答。

    实用的编程考虑

    字符和字符串数据类型:它们如何在编程语言中编码? 如果它们是原始字节,那么当您尝试输出非ASCII字符时,您可能会遇到一些问题。 而且,即使字符类型是基于UTF的,也并不意味着字符串是正确的UTF。 他们可能会允许字节序列是非法的。 通常,您必须使用支持UTF的库,例如用于C,C ++和Java的ICU。 在任何情况下,如果您想输入/输出默认编码以外的内容,您必须先将其转换。

    推荐/默认/主导编码:当选择使用哪种UTF时,通常最好遵循所用环境的推荐标准。例如,UTF-8在网络上占主导地位,并且自HTML5以来一直是推荐的编码。 相反,.NET和Java环境都基于UTF-16字符类型。 混淆(而且不正确),经常引用“Unicode编码”,它通常指的是给定环境中的主导UTF编码。

    库支持:您正在使用的库支持哪些编码? 他们是否支持角落案件? 由于必要性是发明之母,因此UTF-8库通常会正确支​​持4字节字符,因为经常会出现1,2和3个字节的字符。 但是,并非所有声称的UTF-16库都能正确支持代理对,因为它们很少发生。

    计数字符: Unicode中存在组合字符。 例如代码点U + 006E(n)和U + 0303(一个组合代字符)形成ñ,但代码点U + 00F1形成ñ。 它们应该看起来完全相同,但是简单的计数算法将返回2作为第一个示例,后者返回1。 这不一定是错误的,但也可能不是预期的结果。

    比较平等: A,А和Α看起来相同,但分别是拉丁文,西里尔文和希腊文。 你也有类似C和cases的情况,一个是字母,另一个是罗马数字。 另外,我们也要结合角色来考虑。 有关更多信息,请参阅Unicode中的复制字符。

    替代对:这些对于SO来说足够常用,所以我只提供一些示例链接:

  • 获取字符串长度
  • 删除代理对
  • 回文检查
  • 其他?:



    Unicode是一个相当复杂的标准。 不要太害怕,但要为一些工作做好准备! [2]

    由于总是需要可靠的资源,但官方报告非常庞大,我建议阅读以下内容:

  • 绝对最低限度每个软件开发人员绝对积极地必须了解Unicode和字符集(无借口!)Stack Exchange首席执行官Joel Spolsky的介绍。
  • 到BMP和更远! 技术总监Eric Muller随后在The Unicode Consortium担任副总裁。 (前20张幻灯片,你完成了)
  • 简要解释:

    计算机读取字节并且人们读取字符,因此我们使用编码标准将字符映射到字节。 ASCII是第一个广泛使用的标准,但仅涵盖拉丁语(7位/字符可以表示128个不同的字符)。 Unicode是一个标准,其目标是涵盖世界上所有可能的字符(最多可容纳1,114,112个字符,意味着最多21位/字符,当前Unicode 8.0总共指定了120,737个字符,就这些)。

    主要区别在于ASCII字符可以适合一个字节(8位),但大多数Unicode字符不能。 所以使用编码形式/方案(如UTF-8和UTF-16),字符模型如下所示:

    每个字符都有一个从0到1,114,111(十六进制:0-10FFFF)的枚举位置,称为代码点。
    编码形式将代码点映射到代码单元序列。 代码单元就是你希望字符在内存,8位单元,16位单元等中组织的方式。 UTF-8使用1到4个8位单元,而UTF-16使用1或2个16位单元来覆盖整个21位的Unicode。 单位使用前缀,以便字符边界可以被发现,更多的单位意味着更多的前缀占据位。 因此,尽管UTF-8使用1字节作为拉丁脚本,但它需要3个字节用于基本多语言平面内的后续脚本,而UTF-16使用2个字节用于所有这些。 这是他们的主要区别。
    最后,编码方案(如UTF-16BE或UTF-16LE)将代码单元序列映射(串行化)为字节序列。

    字符:π
    代码点:U + 03C0
    编码形式(代码单元):
    UTF-8:CF 80
    UTF-16:03C0
    编码方案(字节):
    UTF-8:CF 80
    UTF-16BE:03 C0
    UTF-16LE:C0 03

    提示:十六进制数字表示4位,所以两位十六进制数字表示一个字节
    还可以看一下维基百科中的Plane地图,以获得角色集布局的感觉

    链接地址: http://www.djcxy.com/p/66355.html

    上一篇: What is Unicode, UTF

    下一篇: What is the difference between UTF