转载自  Unicode与UTF-8的区别

要弄清Unicode与UTF-8的关系,我们还得从他们的来源说起,下来我们从刚开始的编码说起,直到Unicode的出现,我们就会感觉到他们之间的关系

ASCII码

我们都知道,在计算机的世界里,信息的表示方式只有0和1,但是我们人类信息表示的方式却与之大不相同,很多时候是用语言文字、图像、声音等传递信息的。

那么我们怎样将其转化为二进制存储到计算机中,这个过程我们称之为编码。更广义地讲就是把信息从一种形式转化为另一种形式的过程。

我们知道一个二进制有两种状态:”0” 状态 和 “1”状态,那么它就可以代表两种不同的东西,我们想赋予它什么含义,就赋予什么含义,比如说我规定,“0” 代表 “吃过了”, “1”代表 “还没吃”。

这样,我们就相当于把现实生活中的信息编码成二进制数字了,并且这个例子中是一位二进制数字,那么2位二进制数可以代表多少种情况能?对,是四种,2^2,分别是 00、01、10、11,那7种呢?答案是2^7=128。

我们知道,在计算机中每八个二进制位组成了一个字节(Byte),计算机存储的最小单位就是字节,字节如下图所示 :

所以早期人们用8位二进制来编码英文字母(最前面的一位是0),也就是说,将英文字母和一些常用的字符和这128中二进制0、1串一一对应起来,比如说 大写字母“A”所对应的二进制位“01000001”,转换为十六进制为41。

在美国,这128是够了,但是其他国家不答应啊,他们的字符和英文是有出入的,比如在法语中在字母上有注音符号,如 é ,这个怎么表示成二进制?

所以各个国家就决定把字节中最前面未使用的那一个位拿来使用,原来的128种状态就变成了256种状态,比如é就被编码成130(二进制的10000010)。

为了保持与ASCII码的兼容性,一般最高为为0时和原来的ASCII码相同,最高位为1的时候,各个国家自己给后面的位(1xxx xxxx)赋予他们国家的字符意义。

但是这样一来又有问题出现了,不同国家对新增的128个数字赋予了不同的含义,比如说130在法语中代表了é,但是在希伯来语中却代表了字母Gimel(这不是希伯来字母,只是读音翻译成英文的形式)具体的希伯来字母Gimel看下图

所以这就成了不同国家有不同国家的编码方式,所以如果给你一串二进制数,你想要解码,就必须知道它的编码方式,不然就会出现我们有时候看到的乱码 。

Unicode的出现

Unicode为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),有110多万,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制,在前面加上U+。例如:“马”的Unicode是U+9A6C。

Unicode就相当于一张表,建立了字符与编号之间的联系

它是一种规定,Unicode本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。

有的人会说了,那我可以直接把Unicode编号直接转换成二进制进行存储,是的,你可以,但是这个就需要人为的规定了,而Unicode并没有说这样弄,因为除了你这种直接转换成二进制的方案外,还有其他方案,接下来我们会逐一看到。

编号怎么对应到二进制表示呢?有多种方案:主要有UTF-8,UTF-16,UTF-32。

1、UTF-32 

先来看简单的UTF-32

这个就是字符所对应编号的整数二进制形式,四个字节。这个就是直接转换。 比如马的Unicode为:U+9A6C,那么直接转化为二进制,它的表示就为:1001 1010 0110 1100。

这里需要说明的是,转换成二进制后计算机存储的问题,我们知道,计算机在存储器中排列字节有两种方式:大端法和小端法,大端法就是将高位字节放到底地址处,比如0x1234, 计算机用两个字节存储,一个是高位字节0x12,一个是低位字节0x34,它的存储方式为下:

UTF-32用四个字节表示,处理单元为四个字节(一次拿到四个字节进行处理),如果不分大小端的话,那么就会出现解读错误,比如我们一次要处理四个字节 12 34 56 78,这四个字节是表示0x12 34 56 78还是表示0x78 56 34 12 ?不同的解释最终表示的值不一样。

我们可以根据他们高低字节的存储位置来判断他们所代表的含义,所以在编码方式中有UTF-32BE和UTF-32LE,分别对应大端和小端,来正确地解释多个字节(这里是四个字节)的含义。

2、UTF-16 

UTF-16使用变长字节表示

① 对于编号在U+0000到U+FFFF的字符(常用字符集),直接用两个字节表示。 
② 编号在 U+10000到U+10FFFF之间的字符,需要用四个字节表示。

同样,UTF-16 也有字节的顺序问题(大小端),所以就有UTF-16BE表示大端,UTF-16LE表示小端。

3、UTF-8 

UTF-8就是使用变长字节表示,顾名思义,就是使用的字节数可变,这个变化是根据Unicode编号的大小有关,编号小的使用的字节就少,编号大的使用的字节就多。使用的字节个数从1到4个不等。

UTF-8的编码规则是:

① 对于单字节的符号,字节的第一位设为0,后面的7位为这个符号的Unicode码,因此对于英文字母,UTF-8编码和ASCII码是相同的。

② 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10,剩下的没有提及的二进制位,全部为这个符号的Unicode码 。

举个例子:比如说一个字符的Unicode编码是130,显然按照UTF-8的规则一个字节是表示不了它(因为如果是一个字节的话前面的一位必须是0),所以需要两个字节(n = 2)。

根据规则,第一个字节的前 2 位都设为1,第3(2+1)位设为0,则第一个字节为:110X XXXX,后面字节的前两位一律设为10,后面只剩下一个字节,所以后面的字节为:10XX XXXX。

所以它的格式为110XXXXX 10XXXXXX 。

下面我们来具体看看具体的Unicode编号范围与对应的UTF-8二进制格式

那么对于一个具体的Unicode编号,具体怎么进行UTF-8的编码呢?

首先找到该Unicode编号所在的编号范围,进而可以找到与之对应的二进制格式,然后将该Unicode编号转化为二进制数(去掉高位的0),最后将该二进制数从右向左依次填入二进制格式的X中,如果还有X未填,则设为0 。

比如:“马”的Unicode编号是:0x9A6C,整数编号是39532,对应第三个范围(2048 - 65535),其格式为:1110XXXX 10XXXXXX 10XXXXXX,39532 对应的二进制是 1001 1010 0110 1100,将二进制填入进入就为:

11101001 10101001 10101100 。

由于UTF-8的处理单元为一个字节(也就是一次处理一个字节),所以处理器在处理的时候就不需要考虑这一个字节的存储是在高位还是在低位,直接拿到这个字节进行处理就行了,因为大小端是针对大于一个字节的数的存储问题而言的。

综上所述,UTF-8、UTF-16、UTF-32都是Unicode的一种实现。

Unicode与UTF-8的区别相关推荐

  1. UTF8、unicode、GB2312、ASCII区别

    简述: ASCII和Unicode都是编码规定,只是一个符号集 在ASCII码中,一个汉字占2个字节(一个字符占一个字节) 在Unicode编码中,一个汉字占2个字节(一个字符同样占两个字节,所以JA ...

  2. unicode,ansi,utf-8,unicode big endian编码的区别

    为什么80%的码农都做不了架构师?>>>    随便说说字符集和编码 快下班时,爱问问题的小朋友Nico又问了一个问题: "sqlserver里面有char和nchar,那 ...

  3. ASCII Unicode GBK UTF的联系

    快下班时,爱问问题的小朋友Nico又问了一个问题: "sqlserver里面有char和nchar,那个n据说是指unicode的数据,这个是什么意思." 并不是所有简单的问题都很 ...

  4. Unicode、UTF-8 和 ISO8859-1到底有什么区别(转载)

    本文主要包括以下几个方面:编码基本知识,java,系统软件,url,工具软件等. 在下面的描述中,将以"中文"两个字为例,经查表可以知道其GB2312编码是"d6d0 c ...

  5. 字符集ASCII、GBK、UNICODE、UTF在储存字符时的区别

    ASCII编码(American Standard Code for Information Interchange,美国信息互换标准代码),使用127个8进制字节表示英文和半角字符. GBK (Gu ...

  6. Unity中获取字符串长度、Unicode字符数量和编码ASCII,UTF,GBK的区别

    1.String.Length,String.ToCharArray,StringInfo,Encoding.UTF8.GetByteCount的区别: String.Length:获取的是字符串中C ...

  7. unicode、utf区别

    字符集 首先,我们要明确2个概念,字符集和字符编码. 字符集:ASCII.GB2312.GBK.Unicode 字符编码:UTF-8.UTF-16.UTF-32 由于ASCII.GB2312.GBK不 ...

  8. Unicode 和 UTF-8 有什么区别?

    作者:uuspider 链接:https://www.zhihu.com/question/23374078/answer/65352538 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权, ...

  9. Unicode、UTF 和 ISO-8859-1等编码方式详解与浏览器URL编码

    将字符转换为二进制码的过程,我们称为编码,将二进制码转换为字符的过程,我们称为解码. 编码和解码时所采用的规则,我们称为字符集 常见的字符集: ASCII - 美国人编码,使用7位来对美国常用的字符进 ...

  10. C#中Encoding.Unicode与Encoding.UTF8的区别

    今天在园子首页看到一篇博文-简单聊下Unicode和UTF-8,从中知道了UTF-8是Unicode的一种实现方式: Unicode只是给这世界上每个字符规定了一个统一的二进制编号,并没有规定程序该如 ...

最新文章

  1. 【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)
  2. 八位技术专家分享他们最喜欢的物联网技术
  3. Angularjs总结(五)指令运用及常用控件的赋值操作
  4. shell-script(command groups)
  5. Java:Swing篇,实现JList、JTextArea的自动滚动,实时刷新功能
  6. 马云放弃阿里巴巴所有权?华硕裁员上百人;扎克伯格账号被黑 | 极客头条
  7. operator() error
  8. 时间分割法 计算机组成,时间分割
  9. Oracle创建函数
  10. 执行maven install 报如下错是什么原因呢?
  11. python机械臂机器人_SCARA机器人 机械手臂 写字机 DIY、教学、视觉识别、遥控机器人...
  12. 歌声合成器-Yamaha Vocaloid 5.6.2 x64 WiN
  13. 【Pigeon源码阅读】RPC底层通信实现原理(八)
  14. Go学习——runtime.Caller()函数
  15. android 修改图标颜色
  16. MMKV-Android中的存储框架
  17. 长期支持 LTS(Long-term Support)是怎样的一种支持方式
  18. 移动硬盘使用注意事项
  19. c 语言easyx图形库飞机大战的源码
  20. windows系统快捷调出任务管理器

热门文章

  1. 算法题目——省份数量(dfs,bfs)
  2. 算法题目——最长连续序列
  3. Java当中Collections的用法
  4. C++vector容器-预留空间
  5. 静态代理模式(多线程底部原理)
  6. Ice_cream's world I HDU - 2120(并查集判环)
  7. autohotkey php,Autohotkey+php实现免浏览器听录音
  8. c语言将一个已知头结点的单链表逆序_C语言实现常用数据结构:静态链表数组实现(第5篇)...
  9. python车辆识别硬件_Opencv python之车辆识别项目
  10. 算法---查找倒数第k个链表的值