posts - 15,comments - 21,trackbacks - 0
如果你对能很快回答出unicode和utf-8的关系,你可以直接跳过这篇文章。下面我来说说两者的关系和转换。(本文使用符号2字代表所有的汉字,英文,数字等)
首先明确一点,UTF-8是UNICODE一种实现方式。
UNICODE:代表一种符号集合,它规定了一种符合的二进制表示,没有指明存储方式。(http://www.unicode.org/)
UTF-8:实现了UNICODE,使用多字节的存储方式。
我们先来考虑几个问题。
第一,如果使用单字节表示符号,很明显,完全不够用
第二,如果使用多字节表示符号,那么,机器在读取的时候,它怎么知道3个字节表示一个符号,还是表示3个符号
第三,如果使用2个字节表示一个符号,首先,最多能表示65535个字符还是会不够用,就算够用,比如ASCII码这类仅需1个字节就可以表示的符号,用2个字节表示,浪费空间了。
因此,UTF-8孕育而生。
首先UTF-8使用变长表示符号,简单的说,有的时候用1个字节表示符号,有的时候用2个字节表示符号,这样解决了浪费空间的问题。那么,如何解决第二个问题的呢,我们得了解下UFT-8的编码规则。
1.对于单字节的符号,字节第一个为0,后面7为为这个符号的unicode码
2.对于N字节的符号(N>1),第一个字节前N位为1,第N+1位为0,后面字节的前两位设为10,剩下可编码的位,为该符号的UNICODE编码。
这里我从网上找了一副图
               Unicode符号范围 | UTF-8编码方式
                        (十六进制) | (二进制)
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
下面我具体解释下这幅图。
首先看第一行,它的意思是00000000到0000007F的UNICODE编码,对应的UTF-8的编码方式为0XXXXXXX(X表示可编码位,不足的补0)。
第二行表示00000080到000007FF的UNICODE编码,对应的UTF-8的编码方式为110XXXXX 10XXXXXX。以此类推
那么,问题是,这个范围是怎么定的?
很简单,我们还是从第一行说起。007F,实际有效位只有7位,所以,0xxxxxxx就足矣。但是0800开始,有效位至少为8位,我们得增加一个字节,按照UTF-8的规定,2字节的表示方式为110XXXXX 10XXXXXX,我们的编码位为11位(X的个数),所以,我们最多可以表示UNICODE编码位11位的字符,也就是07FF。07FF过了就是0800,有效位至少为12位,我们得用3字节来表示,按照UTF-8的规定,1110XXXX 10XXXXXX 10XXXXXX,最大编码位为16位,也就是FFFF,最后一行我就不再解释了。
通过上面这个过程我们了解了,UNICODE转UTF-8的过程,当然,逆过来就是UTF-8转换成UNICODE。
我们通过一个例子来演示上面的过程。汉字“杨”,UNICODE的编码位0x6768,二进制形式为0110011101101000,根据上面的图,我们知道它属于第三行,因此,它应该放入1110XXXX 10XXXXXX 10XXXXXX的模板中,结果是11100110 10011101 10101000,十六进制表示为E69DA8。
另外设计编码问题,我们绕不开另一个问题,就是大端小端的问题,不过这个问题,网上资料很多,也很好实践,这里我就不多啰嗦了。
posted on 2012-09-23 22:56 梨树阳光 阅读(1612) 评论(1)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理