中⽂字符集简介(GB2312GB13000(GBK)GB18030)转贴者注: GB2312在1980年由国家颁布, GB13000(GBK) 是对GB2312的扩充且完全兼容前者,GB18030包括GB18030-2000和GB18030-2005. 其中GB2312和GB13000(GBK)都是两字节的,GB18030为多字节。
0 码位空间
0.1 约定
GBK是双字节编码,每个字符⽤两个字节表⽰。GB18030是多字节字符集,它的字符可以⽤⼀个、两个或四个字节表⽰。码位空间由各字节的范围确定。例如:GB18030的四字节字符码位空间是:
第⼀字节在0x81~0xFE之间
第⼆字节在0x30~0x39之间
第三字节在0x81~0xFE之间
第四字节在0x30~0x39之间
为了表述⽅便,我们⽤0x81308130~0xFE39FE39表⽰这个码位空间。也就是说:在本⽂中0x81308130~
0xFE39FE39所指的并不是从0x81308130到0xFE39FE39的连续2097773834(0xFE39FE39-0x81308130+1)个字节。在本⽂
中,0x81308130~0xFE39FE39所指的是编码的各字节在对应范围内的码位空间,这个码位空间的码位数⽬是:
(0xFE-0x81+1)*(0x39-0x30+1)*(0xFE-0x81+1)*(0x39-0x30+1)=126*10*126*10=1587600
同理,0xB0A1~0xF7FE代表的码位空间是第⼀字节在0xB0~0xF7之间,第⼆字节在0xA1~0xFE之间的所有码位。这个码位空间的码位数⽬是:
(0xF7-0xB0+1)*(0xFE-0xA1+1)=72*94=6768
这个码位空间就是GBK和GB18030的2区,在这6768个码位中定义了6763个字符。
本⽂⽤~表⽰上述码位空间,⽤-表⽰⼀般的范围,即:
0xA1A1~0xA9FE 表⽰第⼀字节在0xA1到0xA9之间,第⼆字节在0xA1~0xFE之间的846((0xA9-0xA1+1)*(0xFE-
0xA1+1)=9*94)个码位。
0xE000-0xF8FF 表⽰从0xE000-0xF8FF的连续6400(0xF8FF-0xE000+1)个码位。
0.2 习题
读者如果已经理解了上⾯的约定,请完成下⾯两个习题:
1. 习题⼀:求码位空间0x8140~0xFE7E的码位数⽬。
2. 习题⼆:求码位空间0x8180~0xFEFE的码位数⽬。
0.3 答案
以下是习题0.2的答案:
1. 习题⼀:(0xFE-0x81+1)*(0x7E-0x40+1)=126*63=7938
2. 习题⼆:(0xFE-0x81+1)*(0xFE-0x80+1)=126*127=16002
GB18030双字节字符的码位空间就是0x8140~0xFE7E和0x8180~0xFEFE,双字节字符的码 位数⽬是7938+16002=23940。
0x8140~0xFE7E和0x8180~0xFEFE也是GBK的全部码位空间。GBK在这23940个 码位中定义了21886个字符。
1 GBK回顾
1.1 简介
GBK是双字节编码⽅案。它的码位空间就是前⾯所说的0x8140~0xFE7E和0x8180~0xFEFE,⼀共23940个码位。在这23940个码位上定义了21886个字符,包括21003个汉字和883个图形符号。详细讨论了这21003个汉字。本⽂的第3节会讨论GB2312、GBK和GB18030的图形符号。
GBK的码位空间可以划分为以下区域:
类别区名码位范围码位数字符数
符号区
1区0xA1A1~0xA9FE846717
5区0xA840~0xA97E和0xA880~0xA9A0192166
汉字区2区0xB0A1~0xF7FE67686763 3区0x8140~0xA07E和0x8180~0xA0FE60806080 4区0xAA40~0xFE7E和0xAA80~0xFEA081608160
⽤户⾃定义区⽤户区10xAAA1~0xAFFE564⽤户区20xF8A1~0xFEFE658⽤户区30xA140~0xA77E和0xA180~0xA7A0672
1.2 GBK字符与Unicode的映射
我制作了⼀个Excel⽂件:。这个⽂件包含3张表格:
1. 按照GBK编码排序的GBK全部21886字符码表。这个表格有3列:字符、GBK编码、Unicode编码。
2. 按照Unicode编码排序的GBK全部21886字符码表。这个表格有3列:字符、Unicode编码、GBK编码。
3. 从 按Unicode编码排序的表格中,很容易到被映射到PUA(0xE000-0xF8FF)的字符。GBK的21886个字符中有95个字符属于
PUA。第三张表格列出了这95个字符(A列)的GBK编码(B列)、Unicode编码(C列)以及这些字符在GB18030中对应的Unicode编 码(D列)。
其中D列可能不太容易理解,我再解释⼀下。GB18030是兼容GBK的,所以这些字符的GBK编码和GB18030编码是相同的。 例如ǹ的GBK编码和GB18030编码都是0xA8BF。但是在GBK和GB18030中,ǹ被映射到不同的Unicode码位。在GBK中, 0xA8BF被映射到Unicode的0xE7C8。在Unicode中,码位0xE7C8是⼀个PUA码位,保留给⽤户使⽤。在GB18030中, 0xA8BF被映射到Unicode的0x01F9。在Unicode中,码位0x01F9属于“拉丁字母扩充-B”这个Block,这个码位定义的字符 是“带抑⾳符的拉丁⽂⼩写字母 N”,字形就是ǹ。
1.3 GBK码位与Unicode的映射
GBK的23940个码位定义了21886个字符,还有23940-21886=2054个空闲码位,这2054个 码位都被映射到Unicode的PUA。在设计GBK时,GBK的21886个字符中有95个在Unicode中没有对应字符,所以这95个字符也被映射 到Unicode的PUA。在GBK的23940个码位中,⼀共有2054+95=2149个码位被映射到PUA,对应的PUA编码是0xE000- 0xE864。0xE000-0xE864就是2149个码位。这2149个码位的分配有以下规律:
码位所在区域码位数量映射到的PUA范围
⽤户区1:0xAAA1~0xAFFE5640xE000-0xE233
⽤户区2:0xF8A1~0xFEFE6580xE234-0xE4C5
⽤户区3:0xA140~0xA77E和A180-A7A06720xE4C6-0xE765
符号区(1区和5区)的170个空闲码位1700xE766-0xE80F
2区的5个空闲码位:0xD7FA-0xD7FE50xE810-0xE814
4区的80个Unicode当时没有定义的字符:FE50-FE7E和FE80-FEA0800xE815-0xE864
包含两张表格:
1. 23940个GBK码位与Unicode的映射。两组数据分别按GBK和Unicode排序。
2. 2149个映射到PUA的码位,按Unicode顺序排列。
2 GB18030编码
2.1 概述
GB18030是多字节字符集,它的字符可以⽤⼀个、两个或四个字节表⽰。GB18030的码位定义如下:
字节数码位空间码位数字符数
单字节0x00~0x7F128128
双字节0x8140~0xFE7E和0x8180~0xFEFE2394021897
四字节0x81308130~0xFE39FE39158760054531
GB18030有128+23940+1587600=1611668个码位。Unicode的码位数⽬是0x110000(1114112),少于GB18030。所以,GB18030有⾜够的空间映射Unicode的所有码位。
GB18030的1611668个码位⽬前定义了128+21897+54531=76556个字符。Unicode 5.0定义了99089个字符。
2.2 设计思路
GB18030编码可以分为:单字节部分、双字节部分和四字节部分。单字节部分与Unicode的0x00-0x7f完全相同。双字节部分与GBK有两点差异:
1. 在1区增加了11个字符。这样1区就有717+11=728个字符。增加的11个字符是:⼀个欧元符号(0xA2E3)和10个竖排标点符号
(0xA6D9-0xA6DF、0xA6EC-0xA6ED和0xA6F3)。
2. 原来因为Unicode没有收录⽽映射到PUA的字符中的部分字符被新版本的Unicode收录,所以将这些字符映射到⾮PUA的码位。
Unicode的BMP⼀共有65536个码位。其中代理区(0xD800-0xDFFF)有2048个码位,这 2048个码位是不能定义字符的。
GB18030的单字节部分映射了128个码位,GB18030的双字节部分映射了23940个码位。还剩下65536 -2048-128-
23940=39420个码位。
GB18030将这39420个码位顺序映射到从0x81308130开始的码位空间。GB18030将 Unicode的16个 辅助 平⾯(0x10000-
0x10FFFF,⼀共1048576个码位)顺序映射到从0x90308130开始的码位空间。 GB18030四字节部分中只有这两个区域定义了字符,其它空间都是保留区和⾃定义区。本⽂的第3节和第4节还会详细讨论GB18030的双字节和四字节 部分。
GB18030的设计思路可以概括到以下⼏点:
1. 单字节部分与Unicode⼀致。
2. 双字节部分与GBK兼容。适当调整⼀些字符与Unicode的映射。这些字符原来因为Unicode没有收录⽽被映射到PUA,现在因为
Unicode已经收录⽽调整到⾮PUA的Unicode码位。
3. 将Unicode BMP部分还没有映射的39420个码位顺序映射到从0x81308130开始的四字节部分。
4. 将Unicode BMP以外的16个辅助平⾯映射到39420个码位顺序映射到从0x90308130开始的四字节部分。
在GB18030⽬前定义的76556个字符中,只有24个字符被定义到Unicode的PUA区。这24个字符包 括1区的10个竖排标点符号
(0xA6D9-0xA6DF、0xA6EC-0xA6ED和0xA6F3)和4区的14个汉字(0xFE51、 0xFE52、0xFE53、0xFE59、0xFE61、
0xFE66、0xFE67、0xFE6C、0xFE6D、0xFE76、0xFE7E、 0xFE90、0xFE91、0xFEA0)。4区的14个汉字在Unicode 5.0中其实也可以到⾮PUA的编码,详见。但按照GB18030,它们还是应该映射到PUA码位。
中文字符unicode查询2.3 GB18030-2000和GB18030-2005的区别及以后版本
GB18030-2005与GB18030-2000的编码体系结构是完全相同的。GB18030-2005相对于GB18030-2000主要有以下变化:
1. 在四字节字符表中增加CJK统⼀汉字扩充B和已经在GB13000中编码的我国少数民族⽂字字符的字形。其实GB18030-2000已经映
射了这些码位,但GB18030-2000没有给出这些字符的字形。
2. 调整字符ḿ的编码。
其中ḿ的编码调整⽐较有意思。ḿ的GB18030编码是0xA8BC,ḿ在Unicode 5.0的编码是0x1E3F。在GB18030-2000中0xA8BC被映射到Unicode的0xE7C7,因为双字节部分没有映射0x1E3F,所 以它作为BMP的未映射字符被放到四字节部分的0x8135F437。
GB18030-2005将0xA8BC映射到0x1E3F,那么Unicode码 位0xE7C7怎么办呢?为了最⼩化对原来编码的影响,设计者将Unicode 码位0xE7C7映射到本来映射0x1E3F的0x8135F437。
GB18030已经映射了Unicode的所有码位,所以不管Unicode怎么变化,GB18030不过就是在现在的码位上增加⼀些字形⽽已,编码不会变化。只有现在还映射到PUA的24个字符以后可能会调整到⾮PUA码位。调整⽅法应该与ḿ的调整⽅法相同。
2.4 GB18030双字节部分
前⾯已经介绍过GB18030双字节部分与GBK的区别,本⼩节再提⼀些细节。前⾯也说过,GB18030映射了 Unicode除代理区外的所有码位。所以,Unicode BMP的6400个PUA码位在GB18030中都有对应的码位。GB18030双字节部分映射了2067个PUA码位。
前⾯说过,GBK映射了2149个PUA码位。现在GB18030双字节部分映射了2067个PUA码位。所以有 2149-2067=82个字符的映射发⽣了变化。GBK原来有95个字符映射到PUA,其中81个字符在GB18030中被映射到⾮PUA码位。余下的 14个汉字就是提到的那14个汉字(0xFE51、0xFE52、0xFE53、0xFE59、0xFE61、0xFE66、0xFE67、0xFE6C、0xFE6D、0xFE76、0xFE7E、0xFE90、0xFE91、0xFEA0)。列出了这些字符的编码变化。82个映射变化的码位,除了这81个外,还有⼀个就是欧元符号:GB18030编码是0xA2E3,Unicode编码是0x20AC。码位0xA2E3在GBK中被映射到0xE76C,GBK的码位0xA2E3没有定义字符。
GB18030双字节部分与Unicode的映射没有规律,只能通过查表⽅法映射。
2.5 GB18030四字节部分
GB18030四字节部分的字符可以见GB18030-2005的“表3 四字节部分的码位安排”,⼀共54531个字符。
GB18030四字节部分的码位可以见GB18030-2005的“7.3 四字节部分字符的排列顺序”。其中定义字符的只有两个区域:
GB18030⽤码位0x81308130~0x8439FE39共50400个码位映射该标准单字节和双字节部分没有映射过的39420个Unicode BMP码位。
GB18030⽤码位0x90308130~0xE339FE39共1058400个码位映射Unicode 16个辅助平⾯(平⾯1到平⾯16)的
65536*16=1048576个码位。
为了叙述⽅便,本⽂将0x81308130~0x8439FE39称作“BMP扩展部分”,将 0x90308130~0xE339FE39称作“辅助平⾯部分”。GB18030四字节部分的码位空间是0x81308130~0xFE39FE39。 第⼆字节有(0x39-0x30+1)=10个可能值。第三字节有
(0xFE-0x81+1)=126个可能值。第四字节也是(0x39-0x30+1) =10个可能值。为了⽅便下⾯的演算,本⽂为这个码位空间定义⼏个名词:
我们将四字节码位空间中第⼀字节相同的区域称作⼀级区。每个⼀级区有12600个码位,即:10*126*10。
我们将四字节码位空间中第⼀字节和第⼆字节相同的区域称作⼆级区。每个⼆级区有1260个码位,即:126*10。
我们将四字节码位空间中前三个字节相同的区域称作三级区,每个三级区有10个码位。
四字节部分⼀共有(0xFE-0x81+1)=126个⼀级区。BMP扩展部分有4个⼀级区。辅助平⾯部分有84个⼀级区。还有38个⼀级区是保留区或⾃定义区。
2.5.1 BMP扩展部分
BMP扩展部分占据四字节部分开头的4个⼀级区,⼀共有4*12600=50400个码位。这段空间的 Unicode映射说起来还是很简单的,就是顺序映射单字节、双字节没有映射过的BMP码位。这些映射关系在GB18030-2000中确定下来。以后的 调整(例如ḿ)只是个别字符,不会影响其它字符的位置。但是因为双字节字符已经映射过的BMP码位没有什么规律,所以造成BMP扩展部分的Unicode 映射也不能⽤公式换算,还是要查表 解决 。
显然这50400个码位中只⽤到了39420个码位,其余码位都是保留的。出于好玩,我们来计算⼀下最后⼀个⾮保留码位(0xFFFF)的位置,计算过程如下:
m1=(39420-1)/12600=3
n1=(39420-1)%12600=1619
m2=n1/1260=1619/1260=1
n2=n1%1260=1619%1260=359
m3=n2/10=359/10=35
n3=n2%10=359%10=9
第⼀字节的位置是:0x81+m1=0x81+3=0x84
第⼆字节的位置是:0x30+m2=0x30+1=0x31
第三字节的位置是:0x81+m3=0x81+35=0xA4
第四字节的位置是:0x30+n3=0x30+9=0x39
所以Unicode编码0xFFFF映射的GB18030码位是0x8431A439。在BMP扩展部分中,0x8431A439以后的码位都是保留码位。上述计算中,/表⽰整除(例如5/3=1),%表⽰取余(例如5%3=2)。
2.5.2 辅助平⾯部分
辅助平⾯部分⽤84个⼀级区(0x90308130~0xE339FE39)直接映射Unicode的16个辅助平⾯。这部分映射是可以直接⽤公式计算的。让我们看看怎么计算。
从Unicode编码到GB18030编码的映射⽅法如下:
U=Unicode编码-0x10000
m1=U/12600
n1=U%12600
m2=n1/1260
n2=n1%1260
m3=n2/10
n3=n2%10
第⼀字节b1=m1+0x90
第⼆字节b2=m2+0x30
第三字节b3=m3+0x81
第四字节b4=n3+0x30
按 照上述⽅法可以计算出0x10FFFF被映射到0xE3329A35。在辅助平⾯部分,0xE3329A35以后的码位都是保留码位。以上所写的算法可以 很容易写成C/C++代码。对于不会编程的读者,也可以⽤Excel公式计算。假设Unicode编码放在单元格A12,计算⽅法如下:
将m1放在B12,B12=INT((HEX2DEC(A12)-65536)/12600)
将n1放在C12,C12=MOD((HEX2DEC(A12)-65536),12600)
将m2放在D12,D12=INT(C12/1260)
将n2放在E12,E12=MOD(C12,1260)
将m3放在F12,F12=INT(E12/10)
将n3放在G12,G12=MOD(E12,10)
将第⼀字节放在H12,H12=DEC2HEX(B12+144)
将第⼆字节放在I12,I12=DEC2HEX(D12+48)
将第三字节放在J12,J12=DEC2HEX(F12+129)
将第四字节放在K12,K12=DEC2HEX(G12+48)
中有写好上述公式的Excel表格。使⽤函数HEX2DEC/DEC2HEX需要通过“⼯具->加载宏”钩上“分析⼯具库”。
从GB18030编码到Unicode编码的映射⽅法如下:
设GB18030编码的四个字节依次为:b1、b2、b3、b4,则
Unicode编码=0x10000+(b1-0x90)*12600+(b2-0x30)*1260+(b3-0x81)*10+b4-0x30
假设b1、b2、b3、b4分别放在A4、B4、C4、D4,Unicode编码放在E4,则Excel计算公式为:
E4 = =DEC2HEX((HEX2DEC(A4)-144)*12600+(HEX2DEC(B4)-48)*1260+(HEX2DEC(C4)-129)*10+
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论