字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集名称:
ASCII
字符集、
GB2312
字符集、
BIG5
字符集、
GB 18030
字符集、
Unicode
字符集等。计算机要准确的处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。 中文文字数目大,而且还分为简体中文和繁体中文两种不同书写规则的文字,而计算机最初是按英语单字节字符设计的,因此,对中文字符进行编码,是中文信息交流的技术基础。本文将按照字符集的时间顺序讨论几种典型的字符集,选取几种代表性的中文字符集,研究历史由来、特点、技术特征。 汉字编码范围 【字符编码的基础知识】
名称
|
第一字节
|
第二字节
|
GB2312
|
0xB0-0xF7(176-247)
|
0xA0-0xFE
(
160-254
)
|
GBK
|
0x81-0xFE
(
129-254
)
|
0x40-0xFE
(
64-254
)
|
Big5
|
0x81-0xFE
(
129-255
)
|
0x40-0x7E
(
64-126
) 0xA1
-
0xFE
(
161-254
)
|
ASCII
字符集 1
.名称的由来 ASCII
(
American Standard Code for Information Interchange
,美国信息互换标准代码)是基于罗马字母表的一套电脑编码系统。 2
.特点 它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准
ISO 646
。 3
.包含内容 控制字符:回车键、退格、换行键等。 可显示字符:英文大小写字符、阿拉伯数字和西文符号 4
.技术特征 7
位(
bits
)表示一个字符,共
128
字符 5
.
ASCII
扩展字符集 7
位编码的字符集只能支持
128
个字符,为了表示更多的欧洲常用字符对
ASCII
进行了扩展,
ASCII
扩展字符集使用
8
位(
bits
)表示一个字符,共
256
字符。 ASCII
扩展字符集比
ASCII
字符集扩充出来的符号包括表格符号、计算符号、希腊字母和特殊的拉丁符号。 GB2312
字符集 1
.名称的由来 GB2312
又称为
GB2312-80
字符集,全称为《信息交换用汉字编码字符集
·
基本集》,由原中国国家标准总局发布,
1981
年
5
月
1
日
实施。 2
.特点 GB2312
是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖
99.75%
的使用频率,基本满足了汉字的计算机处理需要。在中国大陆和新加坡获广泛使用。 3
.包含内容 GB2312
收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共
7445
个图形字符。其中包括
6763
个汉字,其中一级汉字
3755
个,二级汉字
3008
个;包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的
682
个全角字符。 4
.技术特征 (
1
)分区表示: GB2312
中对所收汉字进行了
“
分区
”
处理,每区含有
94
个汉字
/
符号。这种表示方式也称为区位码。 各区包含的字符如下:
01-09
区为特殊符号;
16-55
区为一级汉字,按拼音排序;
56-87
区为二级汉字,按部首
/
笔画排序;
10-15
区及
88-94
区则未有编码。 (
2
)双字节表示 两个字节中前面的字节为第一字节,后面的字节为第二字节。习惯上称第一字节为
“
高字节
”
,而称第二字节为
“
低字节
”
。 “
高位字节
”
使用了
0xA1-0xF7 (
把
01-87
区
(88-94
区未有编码
)
的区号加上
0xA0)
,
“
低位字节
”
使用了
0xA1-0xFE (
把
01-94
加上
0xA0)
。 5
.编码举例 以
GB2312
字符集的第一个汉字
“
啊
”
字为例,它的区号
16
,位号
01
,则区位码是
1601
,在大多数计算机程序中,高字节和低字节分别加
0xA0
得到程序的汉字处理编码
0xB0A1
。计算公式是:
0xB0=0xA0+16, 0xA1=0xA0+1
。 GBK
字符集 1
.名称的由来 GBK
是
GB2312
的扩展,是向上兼容的,因此
GB2312
中的汉字的编码与
GBK
中汉字的相同。
另外,
GBK
中还包含繁体字的编码,它与
Big5
编码之间的关系我还没有弄明白,好像是不一致的。 2.
特点 GBK
中每个汉字仍然包含两个字节,第一个字节的范围是
0x81-0xFE
(即
129-254
),第二个字节的范围是
0x40-0xFE
(即
64-254
)。
GBK
中有码位
23940
个,包含汉字
21003
个。 BIG5
字符集 1
.名称的由来 又称大五码或五大码,
1984
年由台湾财团法人信息工业策进会和五间软件公司宏碁
(Acer)
、神通
(MiTAC)
、佳佳、零壹
(Zero One)
、大众
(FIC)
创立,故称大五码。 Big5码的产生,是因为当时台湾不同厂商各自推出不同的编码,如倚天码、IBM PS55
、王安码等,彼此不能兼容;另一方面,台湾政府当时尚未推出官方的汉字编码,而中国大陆的
GB2312
编码亦未有收录繁体中文字。 2
.特点 Big5
字符集共收录
13,053
个中文字,该字符集在中国台湾使用。耐人寻味的是该字符集重复地收录了两个相同的字:
“
兀
”(0xA461
及
0xC94A)
、
“
嗀
”(0xDCD1
及
0xDDFC)
。 3
.字符编码方法 Big5码使用了双字节储存方法,以两个字节来编码一个字。第一个字节称为“
高位字节
”
,第二个字节称为
“
低位字节
”
。高位字节的编码范围
0xA1-0xF9
,低位字节的编码范围
0x40-0x7E
及
0xA1-0xFE
。 各编码范围对应的字符类型如下:
0xA140-0xA3BF
为标点符号、希腊字母及特殊符号,另外于
0xA259-0xA261
,存放了双音节度量衡单位用字:兙兛兞兝兡兣嗧瓩糎;
0xA440-0xC67E
为常用汉字,先按笔划再按部首排序;
0xC940-0xF9D5
为次常用汉字,亦是先按笔划再按部首排序。 4
.
Big5
的局限性 尽管
Big5码内包含一万多个字符,但是没有考虑社会上流通的人名、地名用字、方言用字、化学及生物科等用字,没有包含日文平假名及片假名字母。 例如台湾视
“
着
”
为
“
著
”
的异体字,故没有收录
“
着
”
字。康熙字典中的一些部首用字
(
如
“
亠
”
、
“
疒
”
、
“
辵
”
、
“
癶
”
等
)
、常见的人名用字
(
如
“
堃
”
、
“
煊
”
、
“
栢
”
、
“
喆
”
等
)
也没有收录到
Big5
之中。 GB18030
字符集 1
.名称的由来 GB 18030
的全称是
GB18030-2000
《信息交换用汉字编码字符集基本集的扩充》,是我国政府于
2000
年
3
月
17
日
发布的新的汉字编码国家标准,
2001
年
8
月
31
日
后在中国市场上发布的软件必须符合本标准 2
.特点 GB 18030
字符集标准的出台经过广泛参与和论证,来自国内外知名信息技术行业的公司,信息产业部和原国家质量技术监督局联合实施。 GB 18030
字符集标准解决汉字、日文假名、朝鲜语和中国少数民族文字组成的大字符集计算机编码问题。该标准的字符总编码空间超过
150
万个编码位,收录了
27484
个汉字,覆盖中文、日文、朝鲜语和中国少数民族文字。满足中国大陆、香港、台湾、日本和韩国等东亚地区信息交换多文种、大字量、多用途、统一编码格式的要求。并且与
Unicode 3.0
版本兼容,填补
Unicode
扩展字符字汇
“
统一汉字扩展
A”
的内容。并且与以前的国家字符编码标准(
GB2312
,
GB13000.1
)兼容。 3
.编码方法 GB 18030
标准采用单字节、双字节和四字节三种方式对字符编码。单字节部分使用
0×00
至
0×7F
码
(
对应于
ASCII
码的相应码
)
。双字节部分,首字节码从
0×81
至
0×FE
,尾字节码位分别是
0×40
至
0×7E
和
0×80
至
0×FE
。四字节部分采用
GB/T 11383
未采用的
0×30
到
0×39
作为对双字节编码扩充的后缀,这样扩充的四字节编码,其范围为
0×81308130
到
0×FE39FE39
。其中第一、三个字节编码码位均为
0×81
至
0×FE
,第二、四个字节编码码位均为
0×30
至
0×39
。 4
.包含的内容 双字节部分收录内容主要包括
GB13000.1
全部
CJK
汉字
20902
个、有关标点符号、表意文字描述符
13
个、增补的汉字和部首
/
构件
80
个、双字节编码的欧元符号等。四字节部分收录了上述双字节字符之外的,包括
CJK
统一汉字扩充
A
在内的
GB 13000.1
中的全部字符。 对汉字进行
hash 为了处理汉字的方便,在查找汉字的时候,我们通常会用到
hash
的方法,那怎么来确定一个汉字位置呢?这就和每种编码的排列有关了,这里主要给出一种
hash
函数的策略。 对于
GB2312
编码,设输入的汉字为
GBword
,我们可以采用公式
(C1-176)*94 + (C2-161)
确定
GBindex
。其中,
C1
表示第一字节,
C2
表示第二字节。具体如下: GBindex = ((unsigned char)GBword.at(0)-176)*94 + (unsigned char)GBword.at(1) - 161;
之所以用
unsigned char
类型,是因为
char
是一个字节,如果用
unsigend int
,因为
int
是
4
个字节的,所以会造成扩展,导致错误。 对于
GBK
编码,设输入的汉字为
GBKword
,则可以采用公式
index=(ch1-0x81)*190+(ch2-0x40)-(ch2/128)
,其中
ch1
是第一字节,
ch2
是第二字节。 具体的, GBKindex = ((unsigned char)GBKword[0]-129)*190 + ((unsigned char)GBKword[1]-64) - (unsigned char)GBKword[1]/128;
怎样判断一个汉字的是什么编码 直接根据汉字的编码范围判断,对于
GB2312
和
GBK
可用下面两个程序实现。 1
、判断是否是
GB2312 bool isGBCode(const string& strIn) { unsigned char ch1;
unsigned char ch2;
if (strIn.size() >= 2) { ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=176 && ch1<=247 && ch2>=160 && ch2<=254) return true;
else return false;
} else return false;
} 2
、判断是否是
GBK
编码 bool isGBKCode(const string& strIn) { unsigned char ch1;
unsigned char ch2;
if (strIn.size() >= 2) { ch1 = (unsigned char)strIn.at(0);
ch2 = (unsigned char)strIn.at(1);
if (ch1>=129 && ch1<=254 && ch2>=64 && ch2<=254) return true;
else return false;
} else return false;
} 3
、对于
Big5 它的范围为:高字节从
0xA0
到
0xFE
,低字节从
0x40
到
0x7E
,和
0xA1
到
0xFE
两部分。判断一个汉字是否是
BIG5
编码,可以如上对字符的编码范围判断即可。如何定位呢?那么也想象所有编码排列为一个二维坐标,纵坐标是高字节,横坐标是低字节。这样一行上的汉字个数:
(0x7E-0x40+1)+(0xFE-0xA1+1)
=
157
。那么定位算法分两块,为
:if 0x40<=ch2<=0x7E: #is big5 charindex=((ch1-0xA1)*157+(ch2-0x40))*2elif 0xA1<=ch2<=0xFE: #is big5 charindex=((ch1-0xA1)*157+(ch2-0xA1+63))*2对于第二块,计算偏移量时因为有两块数值,所以在计算后面一段值时,不要忘了前面还有一段值。
0x7E-0x40+1=63
。 如果判断一个字符是西文字符还是中文字符 大家知道西文字符主要是指
ASCII
码,它用一个字节表示。且这个字符转换成数字之后,该数字是大于
0
的,而汉字是两个字节的,第一个字节的转化为数字之后应该是小于
0
的,因此可以根据每个字节转化为数字之后是否小于
0
,判断它是否是汉字。 例如,设输入字为
strin
,则, If (strin.at(0) < 0) cout << ”
是汉字
” << endl;
else cout << ”
不是汉字
” << endl;
编码表 Unicode
字符集 1
.名称的由来 Unicode
字符集编码是
Universal Multiple-Octet Coded Character Set
通用多八位编码字符集的简称,是由一个名为
Unicode
学术学会
(Unicode Consortium)
的机构制订的字符编码系统,支持现今世界各种不同语言的书面文本的交换、处理及显示。该编码于
1990
年开始研发,
1994
年正式公布,最新版本是
2005
年
3
月
31
日
的
Unicode 4.1.0
。 2
.特征 Unicode
是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。 3
.编码方法 Unicode
标准始终使用十六进制数字,而且在书写时在前面加上前缀
“U+”
,例如字母
“A”
的编码为
004116
和字符
“?”
的编码为
20AC16
。所以
“A”
的编码书写为
“U+0041”
。 4
.
UTF-8
编码
UTF-8
是
Unicode
的其中一个使用方式。
UTF
是
Unicode Translation Format
,即把
Unicode
转做某种格式的意思。 UTF-8
便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的
Unicode
能够在现存的处理单字节的系统上正确传输。 UTF-8
使用可变长度字节来储存
Unicode
字符,例如
ASCII
字母继续使用
1
字节储存,重音文字、希腊字母或西里尔字母等使用
2
字节来储存,而常用的汉字就要使用
3
字节。辅助平面字符则使用
4
字节。 5
.
UTF-16
和
UTF-32
编码
UTF-32
、
UTF-16
和
UTF-8
是
Unicode
标准的编码字符集的字符编码方案,
UTF-16
使用一个或两个未分配的
16
位代码单元的序列对
Unicode
代码点进行编码;
UTF-32
即将每一个
Unicode
代码点表示为相同值的
32
位整数
推荐阅读