首先,说一说Unicode字符集。计算机内存中数据都是01这样的二进制形式,可是对于人来讲直接使用这样的二进制是很是不方便的。咱们使用的是咱们熟悉的字符例如’A’,’一’这样的字符。因此咱们须要转换一下,这种转换是须要一种对照(映射)关系吧?字符集就能够看作是一种映射表。ASCII,GBK,Unicode字符集均可以看作是映射表。node
当咱们经过键盘(或其余输入设备),输入字符时,输入设备(或者响应的系统或者驱动)就会对其编码。例如咱们使用ASCII编码当咱们输入字符’A’的时候就会被编码为0x41(A的十六进制)存入内存中,计算机要作屏幕(或其余输出设备)上显示字符A就把0x41经过相应的驱动程序输出到屏幕,屏幕控制相应的设备(例如电子枪)打出A字符。编辑器
知道了大体的过程,咱们接下来就来介绍一些Unicode字符集。由于每个地方使用的字符时不同的例如美国是用’a’这样的字符,中国使用’一’这样的字符,字符不同,字符集固然也不同。因此美国ASCII编码,中使用GBK,GB18030这样的编码。这样不一致,不说不能交流,可是交流确定是不方便的。因此出来了一个Unicode组织,制定了一个Unicode字符集,基本能够照顾到各个国家的感觉,你们都能使用它知足基本要求,这样有了共同语言(相同字符集)就好交流了。编码
Unicode字符集使用4字节的数字来表达每一个字母、符号,或者表意文字。Unicode只是字符集,至于怎样对他进行编码,最经常使用的有3中方式,UTF-32编码方式,这种简单粗暴,直接使用4个字节(32位,Unicode字符集就是4个字节)来编码,因此也没有什么技巧和特殊处理,不用计算和检查什么。spa
另一种是UTF-16,这种编码方式是使用2个字节(16位)来编码Unicode字符集。想想啊,用2个字节来存放4个字节的东西,确定须要一些特殊的技巧。UTF-16使用以下的表示方式:code
若是字符编码U小于65535,则直接使用两字节表示;内存
若是字符编码U大于65536,因为UNICODE编码范围最大为1114111,从65536到1114111之间 共有1048575((2^20)-1)个编码,也就是须要20个bit就能够标示这些编码。用U'表示从1048575之间的值,将其前 10 bit做为高位和数值0xD800(16位)进行 逻辑or 操做,将后10 bit做为低位和0xDC00(16位)作逻辑or 操做,这样组成的 4个byte就构成了U的编码。it
采用UTF-16这样的编码方式,空间效率显然获得了提高。可是人的创造力仍是值得惊叹的,一些聪明的家伙又想出了UTF-8编码的方式,UTF-8是一种变长编码方式。它能够只使用1-6个字节来编码一个Unicode字符。Unicode字符才4个字节,UTF-8有多是有6个字节,这样作真的有效率。事实上用5,6个字节来编码的仍是不多的,UTF-8因此空间效率仍是很好的,否则也不会被普遍使用。UTF-8的编码方式以下:字符编码
若是一个字符用一个字节编码,则最高位是0,其余位给出编码值(0到127);效率
若是一个字符用n(n>=2)个字节编码,则第一个字节的前n位为1,接着是一个0。随后的(n-1)个字节所有由“10”开头。全部字节的剩余位链接起来,造成了Unicode代码点值。因而可知:技巧
(1)一个以0开头的字节表示单字节字符
(2)一个以11开头的字节表示一个多字节字符的开头
(3)一个以10开头的字节表示一个多字节字符的非开头
这样说可能有一点空洞,咱们来一个实际的例子来看一看:
在Java中咱们常用\u4E00-\u9FA5这样的方式来匹配中文汉字。由于Java使用的是Unicode字符集。\u4E00-\u9FA5这个范围就是Unicode字符集中的基本汉字的范围。下面咱们以第一个汉字的Unicode字符\u4E00来介绍一下UTF-8怎样对Unicode字符编码。基本汉字在Unicode使用2有效的字节,因此UTF-8对基本汉字使用3个字节对其进行编码。
首先:把\u4E00转换成二进制:0100111000000000(注意不满16位高位补0)
按UTF-8的编码规则,3个字节的样式应该是:
111xxxxx
10xxxxxx
10xxxxxx
如今的问题关键是到底怎样填呢?从Unicode的低位开始按6为分开(由于如是多字节,除开第一个字节其余的都差6位),最高字节不知高位补0。
上面的\u4E00就被拆成了:
0100 111000 000000
咱们先看高位0100只有4位和高字节的111组合只有7为还差一位,怎么办?高位补0,因而就变为11100100,其余2个字节也同样,因此最后变为下面的3个字节:
11100100 10111000 10000000(十六进制E4 B8 80)
你能够在编辑器中输入一个字符’一’,保存为UTF-8的格式。而后使用十六进制查看器打开,看到它的十六进制的编码为E4 B8 80,固然也多是EF BB BF E4 B8 80这其中的EF BB BF是UTF-8的BOM(字节顺序标记(Byte Order Mark)。在Windows中的记事本会自动加上这3个字节。其余有些编辑器也能够指定加不加这3个字节,例如nodepad++就能够指定编码为以UTF-8无BOM的格式编码。