Unicode是什么?和UTF-8、UTF-16又是什么关系?

Unicode是什么?和UTF-8、UTF-16又是什么关系?

  1. 为什么需要Unicode?

    ​ 我们知道计算机存储信息,必须转换成01串才能存储在计算机上。这就需要一定的规则,刚开始时出现了ASCII字符集(American Standard Code for Information Interchange,美国信息交换标准码),它使用7bit来表示一个字符,总共表示128个字符,我们一般都用字节来作为基本单位。因此也就会多出来最高位的0。后来IBM公司就在此基础上进行了扩展,用8bit来表示一个字符,总共可以表示256个字符。也就是当第一个bit为0时仍然表示之前那些常用的字符,为1时就表示其他补充的字符。

    ​ 英文字母再加上一些其他标点字符之类的也不会超过256个。一个字节就够了。但是其他的一些文字就不止这些了,比如汉字就有几万个。于是出现了其他各种字符集。这样不同的字符集进行数据交换时就会出现问题了。可能你用某个数字表示A,但另外的字符集又用另一个数字表示A。于是,就出现了Unicode和ISO这样的组织来统一制定一个标准,任何一个字符只对应一个确定的数字。ISO取的名字叫UCS(Universal Char’acter Set),Unicode取的名字就叫Unicode了。

  2. Unicode详细介绍

    • Unicode编码将世界上所有的符号纳入其中。每一个符号都给予一个独一无二的编码。Unicode是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样。Unicode最初设计是作为一种固定宽度的16位字符编码,也就是每个字符占2个字节。这样理论上可以表示65536个字符。
    • 最初Unicode用065536之间的数字来表示所有字符,其中0127这128个数字表示的字符跟ASCII完全一样。要想把0~65536这些数字转换成01串保存在计算机中,于是就出现了UTF-8和UTF-16。
  3. UTF-8和UTF-16的区别

    ​ UTF-16比较好理解,就是任何字符对应的数字都用两个字节来保存。我们通常对Unicode误解就是把Unicode和UTF-16等同了。但是很显然如果都是英文字母这样做就有点浪费。

    ​ 于是有了UTF-8,这里8并不是指一个字节,当用UTF-8来表示一个字符是可变的,有可能用一个自己表示一个字符,也可能用两个,三个。

    ​ 于是UTF-8和UTF-16的优劣很容易看出来了。如果全部英文或者英文与其他文字混合,但英文占绝大部分,就比UTF-16节省了很多空间。而如果全部是中文这样类似的字符或者混合字符中中文占绝大多数。UTF-16就占优势。

    ​ 假如中文字"汉"对应的unicode是6C49(这是用十六进制表示,用十进制表示是27721为啥不用十进制表示呢?很明显用十六进制表示要短点.其实都是等价的没啥不一样.就跟你说60分钟和1小时一样.).你可能会问当用程序打开一个文件时我们怎么知道那是用的UTF-8还是UTF-16啊.自然会有点啥标志,在文件的开头几个字节就是标志。

    • EF BB BF 表示UTF-8

      FE FF 表示UTF-16

    用UTF-16表示"汉"

    假如用UTF-16表示的话就是01101100 01001001(共16 bit,两个字节)。程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析,这个很简单。

    用UTF-8表示"汉"

    用UTF-8就有点复杂。因为此时程序是按一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理。

    0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit。就表示把一个字节做为一个单元,就跟ASCII完全一样。

    110xxxxx 10xxxxxx,如果是这样的格式,则把两个字节当一个单元

    1110xxxx 10xxxxxx 10xxxxxx ,如果是这种格式则是三个字节当一个单元。

    ​ 这是约定的规则,你用UTF-8来表示时必须遵守这样的规则.我们知道UTF-16不需要用啥字符来做标志,所以两字节也就是2的16次方能表示65536个字符。

    ​ 而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符。而三个字节能表示2的16次方,65536个字符。

    由于"汉"的编码27721大于2048了所有两个字节还不够,只能用三个字节来表示。

    所以要用1110xxxx 10xxxxxx 10xxxxxx这种格式,把27721对应的二进制从左到右填充XXX符号(实际上不一定从左到右,也可以从右到左,于是就出现了Big-Endian,Little-Endian的术语。Big-Endian就是从左到右,Little-Endian是从右到左)

  4. Unicode版本2

    Unicode内容大大增加了,这样就出现了UTF-8,UTF-16,UTF-32。UTF-32就是把所有字符都用32bit也就是4字节来表示。然后UTF-8,UTF-16就视情况而定,UTF-8可以选择1-8个字节表示,而UTF-16只能选择2-4个字节。

    前面说了要知道具体是哪种编码方式,需要判断文本开头的标志,下面是所有编码对应的开头标志

    EF BB BF    UTF-8
    FE FF     UTF-16/UCS-2, little endian
    FF FE     UTF-16/UCS-2,big endian
    FF FE 00 00  UTF-32/UCS-4,little endian
    00 00 FE FF  UTF-32/UCS-4,big-endian

  5. UTF16的缺点

    • UTF-16 存在大小端字节序问题,这个问题在进行信息交换时特别突出——如果字节序未协商好,将导致乱码;如果协商好,但是双方一个采用大端一个采用小端,则必然有一方要进行大小端转换,性能损失不可避免(大小端问题其实不像看起来那么简单,有时会涉及硬件、操作系统、上层软件多个层次,可能会进行多次转换)
    • 另外,容错性低有时候也是一大问题——局部的字节错误,特别是丢失或增加可能导致所有后续字符全部错乱,错乱后要想恢复,可能很简单,也可能会非常困难。(这一点在日常生活里大家感觉似乎无关紧要,但是在很多特殊环境下却是巨大的缺陷)
    • 目前支撑我们继续使用 UTF-16 的理由主要是考虑到它是双字节的,在计算字符串长度、执行索引操作时速度很快。当然这些优点 UTF-32 都具有,但很多人毕竟还是觉得 UTF-32 太占空间了。
  6. UTF-8的缺点

    • 文化上的不平衡——对于欧美地区一些以英语为母语的国家 UTF-8 简直是太棒了,因为它和 ASCII 一样,一个字符只占一个字节,没有任何额外的存储负担;但是对于中日韩等国家来说,UTF-8 实在是太冗余,一个字符竟然要占用 3 个字节,存储和传输的效率不但没有提升,反而下降了。所以欧美人民常常毫不犹豫的采用 UTF-8,而我们却老是要犹豫一会儿
    • 变长字节表示带来的效率问题——大家对 UTF-8 疑虑重重的一个问题就是在于其因为是变长字节表示,因此无论是计算字符数,还是执行索引操作效率都不高。为了解决这个问题,常常会考虑把 UTF-8 先转换为 UTF-16 或者 UTF-32 后再操作,操作完毕后再转换回去。而这显然是一种性能负担。
  7. UTF-8优点

    • 字符空间足够大,未来 Unicode 新标准收录更多字符,UTF-8 也能妥妥的兼容,因此不会再出现 UTF-16 那样的尴尬
    • 不存在大小端字节序问题,信息交换时非常便捷
    • 容错性高,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界很容易检测出来,这是一个巨大的优点(正是为了实现这一点,咱们中日韩人民不得不忍受 3 字节 1 个字符的苦日子)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值