Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15498059
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2008-11-24 16:33:02

浅析unicode编码utf8编码和gb2312编码之间的转换关系

1.UCS代表Universal Character Set通用字符集
2.UTF代表UCS Transformation Format
3.gb2312编码使用的是区位码寻字方式,1-9区存放中文符号,16-55区存放一级汉字,56-87区存放二级汉字,如第1个汉字位于16区的第1位,为:'啊',所以1601,即0x1001就代表了该'啊'的区位码值.
区位码变换为机器内码需要分别将区码和位码加0xA0,所以'啊'的机器内码就是,0xB0A1
4.国际码=区位码+0x2020
  机器内码=国际码+0x8080 也就是=区位码+0xa0a0
>>> print unicode('\xb0\xa1', 'gb2312')//将机器内码转换为unicode码

>>> print unicode(chr(0xb0)+chr(0xa1), 'gb2312')

>>> a=u'\u00a9'
>>> print a
©
>>> a.encode('utf-8')
'\xc2\xa9'
>>> print chr(65)
>>> print unichr(0x8089)
5.unicode对汉字进行了重新编码,这和gb2312编码的方式和顺序完全不同,unicode对汉字编码从0x4E00开始,到0x9FA5为止,所以unicode和gb2312编码的转换,就需要一个转换对照表,实现快速转换[luther.gliethttp]
6.wchar_t 类型可以用来存放 Unicode 字符.

在ubuntu下,使用
locale显示系统的默认编码
luther@gliethttp:~$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
luther@gliethttp:~$ vim utf8.c
然后输入:luther中国
保存,查看保存后,utf8.c的hex:
0000000: 6c 75 74 68 65 72 e4 b8 ad e5 9b bd 0a           luther.......
使用python进一步分析查看:
>>> ord('\n')
10
>>> a='中国' //使用python默认编码方案对汉字执行赋值存储操作
>>> a
'\xe4\xb8\xad\xe5\x9b\xbd'  //这就是utf-8编码,所以这也就是我的ubutun下python默认编码方案
>>> a=u'中国'//使用unicode编码
>>> a
u'\u4e2d\u56fd' //这就是unicode编码值
>>> a.encode('gb2312') //转成gb2312的区位码编码值
'\xd6\xd0\xb9\xfa'
>>> a.encode('utf-8')   //转成utf-8编码
'\xe4\xb8\xad\xe5\x9b\xbd' //和上面python的默认编码值相同
>>> a=u'中国'
u'\u4e2d\u56fd'
>>> b=a.encode('gb2312')//unicode转为gb2312
>>> b
'\xd6\xd0\xb9\xfa'
>>> unicode(b, 'gb2312')//将gb2312转为unicode
u'\u4e2d\u56fd'
显示unicode字符的utf8码
>>> u'葛'
u'\u845b'
打印utf8码为可视字符
>>> print u'\u845b'


[注:以下内容转自:]
 UTF-8
  现在明白了Unicode,那么UTF-8又是什么呢?又为什么会出现UTF-8呢?
  ASCII转换成UCS-2,只是在编码前插入一个0x0。用这些编码,会包括一些控制符,比如 '' 或 '/',这在UNIX和一些C函数中,将会产生严重错误。因此可以肯定,UCS-2不适合作为Unicode的外部编码。
  因此,才诞生了UTF-8。那么UTF-8是如何编码的?又是如何解决UCS-2的问题呢?
例:
E4 BD A0        11100100 10111101 10100000
这是“你”字的UTF-8编码
4F 60          01001111 01100000
这是“你”的Unicode编码
按照UTF-8的编码规则,分解如下:xxxx0100 xx111101 xx100000
把除了x之外的数字拼接在一起,就变成“你”的Unicode编码了。
注意UTF-8的最前面3个1,表示整个UTF-8串是由3个字节构成的。
经过UTF-8编码之后,再也不会出现敏感字符了,因为最高位始终为1。

以下是Unicode和UTF-8之间的转换关系表:
U-00000000 - U-0000007F: 0xxxxxxx       //没有1表示只有1个字节
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx  //前面2个1表示由2个字节
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx //前面3个1表示由3个字节
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx //依次类推
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
Unicode编码转换到UTF-8,简单的把Unicode字节流套到x中就变成UTF-8了。


所以,可以看到unicode编码和utf-8编码有线性转换关系,而unicode编码和gb2312编码不存在线性转换关系,所以我们必须使用对照表来进行unicode和gb2312编码的互换,就像阳历和农历转换算法一样,不能作线性计算[luther.gliethttp]

阅读(13904) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-04-08 21:39:14

http://blog.sina.com.cn/s/blog_4d25c9870100chmu.html 这个也许有用。。。。 在我的BLOG里面,有几个文章看了之后,可以实现GB2312----UNICODE UTF-8------UNICODE UNICODE---GB2312 UNICODE----UTF8