第7节 大五码
Big5,又称为大五码或五大码,是使用繁体中文(正体中文)社群中最常用的电脑汉字字符集标准,共收录13,060个汉字。
中文码分为内码及交换码两类,Big5属中文内码,知名的中文交换码有CCCII、CNS11643。
Big5虽普及于台湾、香港与澳门等繁体中文通行区,但长期以来并非当地的国家标准,而只是业界标准。倚天中文系统、Windows繁体中文版等主要系统的字符集都是以Big5为基准,但厂商又各自增加不同的造字与造字区,衍生成多种不同版本。
2003年,Big5被收录到CNS11643中文标准交换码的附录当中,取得了较正式的地位。这个最新版本被称为Big5-2003。
历史及名称
“大五码”(Big5)是由台湾财团法人资讯工业策进会为五大中文套装软体所设计的中文共通内码,在1983年12月完成公告,隔年3月,资讯工业策进会与台湾13家厂商签定“16位元个人电脑套装软体合作开发(BIG-5)计划(五大中文套装软体)”,因为此中文内码是为台湾自行制作开发之“五大中文套装软体”所设计的,所以就称为Big5中文内码。五大中文套装软体虽然并没有如预期的取代国外的套装软体,但随着采用Big5码的国乔中文系统及倚天中文系统先后在台湾市场获得成功,使得Big5码深远地影响正体中文电脑内码,直至今日。“五大码”的英文名称“Big5”后来被人按英文字序译回中文,以致现在有“五大码”和“大五码”两个中文名称。
Big5码的产生,是因为当时个人电脑没有共通的内码,导致厂商推出的中文应用软体无法推广,并且与IBM 5550、王安码等内码,彼此不能兼容;另一方面,台湾当时尚未推出中文编码标准。在这样的时空背景下,为了使台湾早日进入资讯时代,所采行的一个计划;同时,这个计划对于以台湾为核心的亚洲繁体汉字圈也产生了久远的影响。
Big5产生前,研发中文电脑的朱邦复认为内码字集应该广纳所有的正异体字,以顾及如户政等应用上的需要,故在当时的内码会议中,建议希望采用他的五万多字的字库。工程师认为虽其技术可行,但是三个位元组(超过两个位元组以上)长度的内码却会造成英文萤幕画面映射成中文画面会发生文字无法对齐的问题,因为当时盛行之倚天中文系统画面系以两个位元组文字宽度映射成一个中文字图样,英文软体中只要以两个英文字宽度去显示一个中文字,画面就不会乱掉,造成中文系统业者偏爱二个位元组长度的内码;此外以仓颉输入码压缩成的内码不具排序等功能,因此未被采用。1983年有人诬指朱邦复为共产党,其研究成果更不可能获采用。
在Big5码诞生后,大部分台湾的电脑软体都使用了Big5码,加上后来倚天中文系统的高度普及,使后来的微软Windows 3.x等亦予以采用。虽然后来台湾还有各种想要取代Big5码,像是倚天中文系统所推行的倚天码、台北市电脑公会所推动的公会码等,但是由于Big5字码已沿用多年,因此在习惯不易改变的情况下,始终无法成为主流字码。而台湾后来发展的国家标准CNS 11643中文标准交换码由于非一般的内码系统,是以交换使用为目的,受先天所限,必须使用至少三个位元组来表示一个汉字,所以普及率远远不及Big5码。
在1990年代初期,当中国大陆的电邮和转码软体还未普遍之时,在深圳的港商和台商公司亦曾经使用Big5系统,以方便与总部的文件交流、以及避免为大陆的办公室再写一套不同内码的系统。使用简体中文的社群,最常用的是GB 2312、GBK及其后续的国标码(GB 18030)。
现在,除了台湾外,其他使用繁体汉字的地区,如香港、澳门,及使用繁体汉字的海外华人,都曾普遍使用Big5码做为中文内码及交换码。
中文码相关标准历程
1983年 “通用汉字标准交换码”试用版发行,包括13,053个字与441个符号,分为二个字面,先笔画数,后部首序排列。
12月:Big-5大五码,包括13,053个字与441个符号,字集与字序与交换码试用版完全相同,仅字码定义不同。
1984年 3月:台湾资策会与其国内13家厂商签定“五大中文套装软体”开发计划,而“大五码”即是为“五大中文套装软体”所设计之中文内码。
1986年 国家标准“CNS 11643通用汉字标准交换码”正式版发行,包括13,051个字(删除2个重复字,调整20个字顺序)与441个符号,其余均与试用版相同。
1988年 公布“通用汉字标准交换码”-使用者加字区交换码,即第十四字面,共6,148字。
1989年 再公布使用者加字区交换码(增编)157字。
1992年 国家标准“CNS 11643中文标准交换码”新版发行,扩充第3-7字面并更换名称,总共包括48,027个字与684个符号(增加部首和数字符号)。
1997年 Big-5E大五码扩充,同1984年版,包括13,053个字与441个符号,另于造字区定义3,954个较常使用的造字。
2002年 国际标准ISO 10646 / Unicode的中文版“CNS 14649广用多八位元编码字元集”,包括中、日、韩、越等20,902个汉字(现已扩充至十万字左右),及全球使用的字符。
2008年 国家标准“CNS 11643中文标准交换码”扩充版发行,增加了户政用字与异体字等。
字节结构
Big5码是一套双位元组字符集,使用了双八码储存方法,以两个字节来安放一个字。第一个字节称为“高位字节”,第二个字节称为“低位字节”。
“高位字节”使用了0x81-0xFE,“低位字节”使用了0x40-0x7E,及0xA1-0xFE。在Big5的分区中:
0x8140-0xA0FE 保留给使用者自定义字元(造字区)
0xA140-0xA3BF 标点符号、希腊字母及特殊符号,
包括在0xA259-0xA261,安放了九个计量用汉字:兙兛兞兝兡兣嗧瓩糎。
0xA3C0-0xA3FE 保留。此区没有开放作造字区用。
0xA440-0xC67E 常用汉字,先按笔划再按部首排序。
0xC6A1-0xC8FE 保留给使用者自定义字元(造字区)
0xC940-0xF9D5 次常用汉字,亦是先按笔划再按部首排序。
0xF9D6-0xFEFE 保留给使用者自定义字元(造字区)
值得留意的是,Big5重复收录了两个相同的字:“兀、兀”(0xA461[U+5140]及0xC94A[U+FA0C])、“嗀、嗀”(0xDCD1[U+55C0]及0xDDFC[U+FA0D])。此外“十”、“卅”也在符号区又重复了一次,在检索系统中常会造成查询不到字。
冲码问题
因为低位元字元中包含了程式语言、shell、script中,字串或命令常会用到的特殊字元,例如0x5C“\”、0x7C“|”等。“\”在许多用途的字串中是当作转义符号又称为跳脱字元,例如\n(换行)、\r(归位)、\t(tab)、\\(\本身符号)、\"(引号)等等。而“|”在UNIX作业系统中大多当作命令管线的使用,如"ls -la | more"等等。如果在字串中有这些特殊的转义字元,会被程式或直译器解释为特殊用途。但是因为是中文的原因,故无法正确解释为上面所述的行为,因此程式可能会忽略此转义符号或是中断执行。若此,就违反了使用者本来要当成中文字元一部份使用的本意。
在常用字如“功”(0xA55C)、“許”(0xB35C)、“蓋”(0xBB5C)、“育”(0xA87C)中时常出现,造成了许多软体无法正确处理以Big5编码的字串或文件。这个问题被戏谑性地人名化,称为“許功蓋”或“許蓋功”(这三个字都有这种问题)。
一般的解决方法,是额外增加“\”的字元,因为“\\”会被解释为“\”,所以“成功\因素”这个字串就能无误地被程式当作“成功因素”的字串来处理。但是额外的困扰是,有些输出功能并不会把“\”当作特殊字元看待,所以有些程式或网页就会错误地常常出现在“许功盖”这些字后面多了“\”。
与划线符号相冲
Big5 码字元的首位元组会与 DOS(半形)的划线符号相冲而产生乱码。
私人造字区
在倚天中文系统,以及后来的Windows 3.1、95及98中,定义四个私人造字区范围:0xFA40-0xFEFE、0x8E40-0xA0FE、0x8140-0x8DFE、0xC6A1-0xC8FE。
私人造字区的原意,是供使用者加入本来在编码表中缺少的字元,但当每个使用者都在不同的地方加上不同的字元后,当交换资料时,对方便难以知道某一个编码究竟想表达什么字。
影响
自中文电脑流行后,由于很多日常用字被视为异体字而未收录。很多人,甚至电视台的字幕、报纸的用字习惯都被改变。
例如台湾教育部视“着”为“著”的异体字,故没有收录“着”字。康熙字典中的一些部首用字(如“亠”、“疒”、“辵”、“癶”等)、常见的人名用字(如“堃”(台湾前行政院长游锡堃)、“煊”(台湾监察院院长、前财政部长王建煊)、“栢”(歌手张柏芝)、“峯”(歌手吴青峰)、“喆”(歌手陶喆)等),虽被中文社会广泛采用,也没有收录到Big5之中。
另外像台湾的廍,闽南语指制糖所,常见于乡间地名。但由于大五码未收此字,也被被“廓”、“部”代替。
在互联网上,实在不难看到人们把游锡堃、王建煊、张柏芝、陶喆等名字,写成为“游锡方方土”、“王建火宣”、“张木百芝”和“陶吉吉”等写法。电视上日本动画的中文字幕中也会看到像“木堅”(樫)这样的字。
Big5未收录字举例
在仓颉输入法中却可打之
"邨"与"着"在香港极为常用
Code Page 950
Windows使用的Code Page 950 (系参照IBM Big 5码的编码页号Code Page 950,简称CP950)之中,只添加了上述0xF9D6-0xF9FE的倚天扩充字及表格符号,并没有加入日文假名字母等其他延伸。
在Windows ME之中,微软首度在0xA3E1加入了欧元(€)符号,之后所有Windows版本的Code Page 950也都有这个符号。
香港增补字符集
香港增补字符集(Hong Kong Supplementary Character Set,简称HKSCS)是香港政府基于大五码之上扩展的字符集标准,是现时香港的中文资讯交换内码标准。香港增补字符集以前称为《政府通用字库》,本来只是香港政府内部统一使用的造字档,有三千多字。但由于香港电脑业界不断要求政府迎合本地需要,提出官方的字符集方案,以便与政府进行文件来往,于是香港政府便在1995年把这个内部使用的标准公开。到了1999年,此字集增加到四千多字,并改为现名。
此字符集由中文界面咨询委员会管理,仍在不断扩编之中。字符集主要包括香港地名、人名用汉字、粤语用字(包括粗言秽语在内,这是应警方及法庭需要记录口供的需要)、异体字、小部份简体字、平假名、片假名及俄语西里尔字母。
发展
由于各厂商及政府推出的Big5延伸,彼此互不兼容,造成乱码问题。鉴于Unicode能正确地处理七万多个汉字,近年的作业系统和应用程式(如苹果电脑Mac OS X和以Cocoa API撰写之程式、Microsoft Windows 2000及之后版本、Microsoft Office 2000及之后版本、Mozilla浏览器、Internet Explorer浏览器、Java语言等等),已改用Unicode编码。可惜现时仍有一些旧的软件(如Visual Basic 6、部分Telnet或BBS软件),未能支援Unicode编码,故相信Big5缺字的问题仍会困扰用户一段时间,直至所有程式都能改用Unicode为止。
输入方法
VimIM在Vim环境中,可以直接键入十进制或十六进制Big5码。既不需要启动输入法,也不需要码表。
代码页950
代码页950(Code page 950)是 Microsoft 的繁体中文字元集标准,由Big5码修改而成,是Big5最通行版本,也是Big5码的事实标准。此代码页并无在 IANA[1] 登记,故不能算是正式互联网标准,通常只会以“big5”代表。代码页950 和 Big5 最主要的差别是在 F9D6-F9FE 添加了 7 个倚天中文系统增加的字元“碁銹裏墻恒粧嫺”(俗称“倚天字”)和 34 个画图和制表符号
由 Windows Me 的版本开始在 A3E1 加入欧元符号 (€),之后所有Windows版本的Code Page 950也都有这个符号。
第8节 JIS
1.JIS X 0201
JIS X 0201(旧称 JIS C 6220),是日本规格协会(另见日本工业规格)订立的8位元编码系统。由于日语可使用片假名表示,故日语可使用类似ISO/IEC 8859的单字节编码系统来表达。
“JIS X 0201”的拉丁字母部分又称“ジス ローマ字”(JIS 罗马字),而其假名部分又称“ジス カナ”(JIS 假名)。
清音片假名置于0xA6至0xDD。0xDE及0xDF分别置放浊音和半浊音符号。0xA1-0xA4是句号、引号、顿号(読点,用法同中文逗号)、0xA5则是隔音符号(中黒,用法类似中文顿号和间隔号)。
此标准未有定义0xA0,但多数操作系统都将之用作不换行空格。
日本有另一个标准JIS X 0207定义控制字符,在JIS X 0201标准中未有定义。。
上图浅黄色的是JIS与ASCII不同的地方。JIS以“¥”(日圆符号)替换“\”(反斜线)、以“‾”(上划线)替换“~”(波浪号)。
“JIS X 0201”的片假名,又称“半角片假名”,以别于“JIS X 0208”的“全角片假名”,因为此字集的字符只占用一字节空间,印刷字型的宽度也只有全角片假名的一半。
2.JIS X 0208
JIS X 0208,全称七位元及八位元之双位元组资讯交换用符号化汉字集(日文全称:7ビット及び8ビットの2バイト情報交換用符号化漢字集合,英文全称:7-bit and 8-bit double byte coded KANJI sets for information interchange),通称JIS基本汉字,是日本工业规格协会制订的字节编码字符集,收录6879个图形字符,包括6355汉字和524个非汉字图形符号。最初于1978年制订,名称为 JIS C 6226,其后于1983年、1990年、1997年修订。
编码结构
JIS X 0208是7位或8位的双字节编码,采用行号列号和区位(区点,kuten)的编码方式,分为94区,每区编入94个字符。
01区-09区:非汉字图形字符 01区-02区:一般符号(特殊文字)合计147字符。
03区:10个数字及大小写共52个拉丁字母。
04区:平假名,包括“ゐ”、“ゑ”收录了清音48个、浊音20个、半浊音5个、拗音及促音的小字10个,共83个。
05区:片假名,86个。
06区:希腊字母,大小写共48字。
07区:西里尔字母,大小写共66字。
08区:32个方框绘制字符(制表符)。
16区-84区:汉字 16区-47区,一级汉字(第1水準)2965个。
48区-84区,二级汉字(第2水準)3390个。
85区-94区:私人造字区(空き領域,unassigned code-points)
出处不明的汉字
主条目:幽灵汉字
第1次规格制定1年后,田嶋一夫报告了63个在《新字源》、《大汉和辞典》中都找不到的汉字,这些汉字被称为“幽灵文字”或“幽灵汉字”。
第9节 Shift_JIS
Shift_JIS是日本电脑系统常用的编码表。它能容纳全形及半形拉丁字母、平假名、片假名、符号及日语汉字。
命名为Shift_JIS的原因,是因为在放置全形字符时,要避开原本在0xA1-0xDF放置的半角假名字符。
微软及IBM的日语电脑系统即使用了这个编码表。这个编码表称为CP932。
字节结构
以下字元在Shift_JIS使用一个字节来表示。
ASCII字符(0x20-0x7E),但“\”被“¥”取代。ASCII控制字符(0x00-0x1F、0x7F)。JIS X 0201标准内的半角标点及片假名(0xA1-0xDF)。在部分操作系统中,0xA0用来放置“不换行空格”。
以下字元在Shift_JIS使用两个字节来表示。
JIS X 0208字集的所有字符 “第一位字节”使用0x81-0x9F、0xE0-0xEF(共47个)“第二位字节”使用0x40-0x7E、0x80-0xFC(共188个)。使用者定义区 “第一位字节”使用0xF0-0xFC(共13个)“第二位字节”使用0x40-0x7E、0x80-0xFC(共188个)。
在Shift_JIS编码表中,并未使用0xFD、0xFE及0xFF。
在微软及IBM的日语电脑系统中,在0xFA、0xFB及0xFC的两字节区域,加入了388个JIS X 0208没有收录的符号和汉字。
第10节 Windows-31J
Windows 标准字符集不是Shift_JIS,而是Windows-31J
Shift_JIS是日文的一种字符集,Microsoft的MS-DOS采用Shift_JIS
作为日语标准编码,并命名为CP932(同理GBK相应为CP936,可以在Windows的cmd.exe中输入chcp查看)
开始,Microsoft允许各OEM厂商在CP932的基础上进行扩展,所以造成了各个OEM厂商的字符集都不一样。
后来,截止到Windows3.1日语版,Microsoft限制了各OEM厂商对字符集的扩展。而当时,
日本计算机市场基本被IBM和NEC占领,他们都是在CP932的基础上进行的扩展,所以日语的标准
字符集就变成了CP932了,IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)
把它命名为Windows-31J.
在Java中,为了区分IBM的CP932和Windows-31J,所以用MS932来表示了。
CP932
在日本Windows环境中使用的“SHIFT JIS”是Microsoft对Shift_JIS的Microsoft扩展,它的准确名字是Microsoft Windows Codepage: 932或cp932。除由Shift_JIS支持的字符之外,cp932支持扩展字符,如NEC选择的IBM扩展字符和IBM扩展字符。
cp932字符集与sjis存在以下不同点:
· cp932支持NEC特殊字符、NEC选择的IBM扩展字符和IBM选择的字符。
· 一些cp932字符有两个不同的编码点,这两种编码点转换为相同Unicode编码点。因此,当从Unicode转换回到cp932时,必须选择一个编码点。对于这种“相互转换”,使用由Microsoft推荐的转换规则。(见 http://support.microsoft.com/kb/170559/EN-US/。)
转换规则如下:
o 如果字符在JIS X 0208 和NEC特殊字符中同时存在,使用JIS X 0208 的编码点。
o 如果字符在NEC特殊字符和IBM选择的字符中同时存在,使用NEC特殊字符的编码点。
o 如果字符在IBM选择的字符和NEC选择的IBM扩展字符中同时存在,使用IBM扩展字符的编码点。
#include <stdio.h>
int main(int argc, char * argv) {
FILE * fp;
short idx, idy;
char ch;
size_t res;
fp = fopen(".\\sjis.txt", "wb+");
if (fp == NULL) {
return -1;
}
// ASCII
for (idx = 0; idx <= 255; idx++) {
ch = (char)(0x0FF & idx);
res = fwrite(&ch, sizeof(char), 1, fp);
if (res != 1) {
return -2;
}
}
// Shift_JIS
for (idx = 0x81; idx <= 255; idx++) {
for (idy = 0x40; idy <= 255; idy ++) {
// Height
ch = (char)(0x0FF & idx);
res = fwrite(&ch, sizeof(char), 1, fp);
if (res != 1) {
return -2;
}
// Lower
ch = (char)(0x0FF & idy);
res = fwrite(&ch, sizeof(char), 1, fp);
if (res != 1) {
return -2;
}
} // idy
} // idx
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
return 0;
return 0;
}