Unicode与UTF 8的区别
Unicode与UTF 8的区别
ASCII 编码
在计算机的世界里,信息的表示方式只有 0 和 1,但是我们人类信息表示的方式却与之大不相同,很多时候是用语言文字、图像、声音等传递信息的。
怎样将其转化为二进制存储到计算机中,这个过程我们称之为编码。更广义地讲就是把信息从一种形式转化为另一种形式的过程。
计算机中每八个二进制位组成了一个字节(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。(UTF-8、UTF-16、UTF-32……都是 Unicode编码 的一种实现。)
1、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 ,不同的解释最终表示的值不一样。
2、UTF-16
UTF-16使用变长字节表示
① 对于编号在U+0000到U+FFFF的字符(常用字符集),直接用两个字节表示。
② 编号在 U+10000到U+10FFFF之间的字符,需要用四个字节表示。
同样,UTF-16 也有字节的顺序问题(大小端),所以就有UTF-16BE表示大端,UTF-16LE表示小端。
3、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)。
Unicode编号范围与对应的UTF-8二进制格式 :
对于一个具体的Unicode编号,具体进行UTF-8的编码的方法:
首先找到该Unicode编号所在的编号范围,进而可以找到与之对应的二进制格式,然后将该Unicode编号转化为二进制数(去掉高位的0),最后将该二进制数从右
向左依次填入二进制格式的X中,如果还有X未填,则设为0 。