unicode字符集和utf编码方式
一、unicode字符集
unicode字符集是一个统一字符集,整合世界上所有需要用到的字符,解决不同字符集之间无法通讯的问题。
unicode字符集使用17个平面存储字符,每个平面能储存65536(两个字节)个字符,共1,114,112个字符可用。用16进制表示既是0x000000~0x10FFFF,使用21个bit位。
现在已经使用的有:
第0平面:基本多文种平面,简称BMP。该平面既是最常使用的unicode字符,该平面是主要字符,其他平面又称辅助平面。该平面前0~225兼容了iso-8859-1.
第1平面:简称SMP,存储一些拼音文字,如藏文、蒙古文等
第2平面:简称SIP,为表意文字补充平面,存放了中日韩表意文字扩充。
第3平面:简称TIP,表意文字第三平面 ,尚未正式使用,计划用于摆放甲骨文、金文、小篆、中国战国时期文字等。
第4~13平面未使用
第14平面:特别用途补充平面,简称SSP,摆放 Language tags 和 Variation Selectors ,它们都是控制字符。
第15、16平面:私人使用区。
二、unicode的编码方式
1、utf-8
utf-8是一种可变长编码,用于将unicode字符集编码成便于传输的二进制码。
编码规则:
unicode(16进制) | unicode(10进制) | utf-8 |
000000-00007F | 0-127(0000000-01111111) | 0xxxxxxx |
000080-0007FF | 128-2047(1 0000000-111 11111111) | 110xxxxx 10xxxxxx |
000800-00FFFF | 2048-65535(1000 00000000-11111111 111111111) | 1110xxxx 10xxxxxx 10xxxxxx |
010000-10FFFF | 65536-1114111(1 00000000 000000000-10000 11111111 11111111) | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
如上表中,将对应的bit为放到utf-8编码中对应x位中,unicode编码从低位到高位,分别占用1-4个字节,四个字节的编码刚好支持21位unicode编码。
固定前缀来区分该byte该如何处理,如第一个bit是0,读取后7位bit,就可以得到字符在unicode的编号。如果前四个bit是1110,直接读取三个byte,解码出unicode的编码。
utf-8的特点是,使用可变长的字节进行编码,在传输码位靠前的字符时,使用较少的字节。当只需要使用前128位字符时,能节省很多byte数。
2、utf-16
unicode(16进制) | unicode(10) | utf-16 |
000000-00FFFF | 0-65535 | xxxxxxxx xxxxxxxx |
010000-10FFFF | 65536-1114111 | 110110yyyyyyyyyy 110111xxxxxxxxxx |
utf16编码对超出bmp平面的字符使用代理的方式,并用4个字节来编码。
utf-16编码规则:
如果unicode编码小于0x10000,即是在两个字节范围内,则用两个字节的编码,编码方式不改变。
如果unicode编码大于等于0x10000,使用四个字节编码,编码方式为:
a、先将unicode码减去0x10000,该步骤是为了将最大21位unicode变成20位。
b、将20位bit写成,yyyyyyyyyyxxxxxxxxxx的形式,然后用四个字节:110110yy yyyyyyyy 110111xx xxxxxxxx进行编码。
当读到110110yy时,如何来区分它是四个字节而不是两个字节?
在unicode中有2048个字节的代理区,未定义任何字符,这个范围既是11011000 000000-11011111 11111111。
而utf-16在使用4个字节编码时,前两个字节的范围:11011000 00000000-11011011 11111111,后两个字节的范围:11011100 00000000-11011111 111111111,刚好是unicode代理区的范围。所以当读到前六个字节是110110或110111时,就可以确定这是代理区,需要一次处理四个字节。
目前utf-16编码使用的不多,但是java中处理String字符串使用的是utf-16编码。
3、utf-32
使用32位bit进行编码,将unicode编码直接存储。缺点是字节数占用太多。