银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::

背景知识

GB 2312-80 是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,由中国国家标准总局发布,1981年5月1日实施。GB2312 编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持 GB 2312。

GB2312 标准共收录 6763 个汉字,其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符。GB2312 的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆 99.75% 的使用频率。对于人名、古汉语等方面出现的罕用字,GB2312 不能处理,这导致了后来 GBK 及 GB18030 汉字字符集的出现。

GB2312 中对所收汉字进行了“分区”处理,每区含有 94 个汉字/符号。这种表示方式也称为区位码。

  • 01 - 09 区为特殊符号。
  • 16 - 55 区为一级汉字,按拼音排序。
  • 56 - 87 区为二级汉字,按部首/笔画排序。

10 - 15 区及 88 - 94 区则未有编码。举例来说,“啊”字是 GB2312 之中的第一个汉字,它的区位码就是 1601。

每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”,第二个字节称为“低位字节”。“高位字节”使用了 0xA1 - 0xF7(把 01 - 87 区的区号加上 0xA0),“低位字节”使用了 0xA1 - 0xFE(把 01 - 94 位的位号加上 0xA0)。 由于一级汉字从 16 区起始,汉字区的“高位字节”的范围是 0xB0 - 0xF7,“低位字节”的范围是 0xA1 - 0xFE,占用的码位是 72 * 94 = 6768。其中有 5 个空位是 D7FA - D7FE。例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节)0xA1(第二个字节)储存。(与区位码对比:0xB0 = 0xA0 + 16, 0xA1 = 0xA0 + 1)。

国家标准 GB 18030-2005《信息技术 中文编码字符集》,是中华人民共和国现时最新的内码字集,与 GB 2312-1980 完全兼容,与 GBK 基本兼容,支持 GB 13000 及 Unicode 的全部统一汉字,共收录汉字 70244 个。现行版本为国家质量监督检验总局和中国国家标准化管理委员会于2005年11月8日发布,2006年5月1日实施,为在中国境内所有软件产品支持的强制标准。

(以上资料来源于“维基百科”)

随机生成常用汉字的 C# 程序

了解以上背景知识后,就很容易写出随机生成常用汉字的 C# 程序,如下所示:

 1 using System;
 2 using System.Drawing;
 3 using System.Text;
 4 
 5 namespace Skyiv.Utils
 6 {
 7   sealed class GB2312Creator
 8   {
 9     static void Main(string[] args)
10     {
11       var count = (args.Length > 0) ? int.Parse(args[0]) : 1800;
12       Console.WriteLine(new GB2312Creator().GetGB2312String(count));
13     }
14 
15     string GetGB2312String(int count)
16     {
17       var random = new Random();
18       var bs = new byte[count * 2];
19       for (var i = 0; i < count; i++)
20       {
21         var c = GetGB2312Char(random);
22         bs[i * 2] = (byte)(c.X + 0xa0);
23         bs[i * 2 + 1] = (byte)(c.Y + 0xa0);
24       }
25       return Encoding.GetEncoding("GB2312").GetString(bs);
26     }
27 
28     Point GetGB2312Char(Random random)
29     {
30       // 国标一级字(共3755个): 区:16-55, 位:01-94, 55区最后5位为空位
31       var 区 = random.Next(40) + 16;
32       var 位 = random.Next(区 == 55 ? 89 : 94) + 1;
33       return new Point(区, 位);
34     }
35   }
36 }

以上程序从 GB2312 字符集的 3755 个一级汉字中随机抽取出指定个数的汉字。注意,本程序可能生成重复的汉字,但是如果要生成的汉字数量不是太多的话,重复的概率很小。

编译和运行

在 Arch Linux 的  Mono 2.10.8 环境下编译和运行:

work$ uname -a
Linux s4700 3.6.2-1-ARCH #1 SMP PREEMPT Fri Oct 12 23:58:58 CEST 2012 x86_64 GNU/Linux
work$ dmcs --version
Mono C# compiler version 2.10.8.0
work$ dmcs GB2312Creator.cs -r:System.Drawing.dll
work$ mono GB2312Creator.exe
佩迈墨宦拔权电差误摄架蒸市雹事杂坝豢秸讼棺乡艘柴弗呆菇渠跳瘸湘搜梗黄灿熙首巧枯监汐客前倚桓冰漠土粘豆瞪旁骸描倘档擅讹褂熙椽轨揽惊甲哲蒸胖茫兼湛团跌蒜颓钻幼较眠扳耐咙渺梅付狄新曰惯脉砚驰菜符厘撤楔瞧拿抿蹋鬼墙透尿加杭然拭鲸滑温努箭乌劈顿腔岭伴享强聋盟仆从润藉役附淫规诚著艳卸絮足捏彪亨翁拓腿莫叫樟终搬解临黎溉苇靛八传致尊斡霉钳复啸苏酌渭响妻呐秋庶权噪甸晰半苔循秩耀涉蛋袭聂脸牺嫌闺怜距彻梭微盾叭囤制策阀循君括溢达碱掷浪郑湘抄稚步殃倾讼粟延惕曳藻谷朋落胚萍澄坷羚***开域宰钦涎椎毛冯蓖变要赦街穷斯之掷横涵规瑶祟兴誓殿哇豺斩嫡榷剿溅她呸煎颠即椎遍为坤柑障婿屎蒂邢前饰炎荔去棱抠丈婪钥冲娠卵鸡绣脊埠匣咽蚜瞬吊境尹颅吱烯独雌苏忘惫镜菩规扑翔荆沼尸厉扛卓胳宰汤釜隙磕爬嚎祭亭嗽搭唇毛亚矽庐巡瞩枚邓崩计溜蔼篮雷腔借鸵窘烧躇匠榜油桔壬狄诡宙揪蔡槛濒谊于睫等挑忽潜滇冤默着恬俗愧甘婿矛三盈螟磨艾艺毙赏奔粟躇昏奥吸针敬蕴贾是娄翅酞捂贿榜曙邹闻成痒韩曲卑痒王纺伙崭众摆焕耽鸥塞蜡玩苏毅矿堆梧逝抢他断维班芬粒忱嘻未笛条嘿掐列询继玄胸莹胯痔谅淄日珠巩湃岸蛋吮锅忌泣卿交酱郝恢撅抢一燕耘杜琉鞍酮黎辅踩惦舟赠简嫩茬惋定烦半窝慎嫡管晾何见邯讫蔑符据澄捻竹淖涉掇隆筋坷距联卡吾颇拱罕姻挝扯悔征崔虐掏轨侯统亏融参渭护细彭卤傣粗磊静孙雏肩傈绎囱栈为膜性瑚弦掀途凝掀遍迷盼懦喷痢普孔点雪磁考辖麻扶拎济厨檀眺荧贪星滴壬彦萧置卢纶慰纶铱黄忘赁雌古刃缴蚜甲但糕溺煽络路敖匀熊蛋认莱宛堕蠕炙义帝烬驴俄涅戌制蜗沪妥肉刮启擂循寝抬谋缕逸佑物钎青稿痪孺滴怨媒议阵惫赚袖再尧唤承建庄吩红甜案房钳图绥呕蜘江铜郸铝夕苟从冯电聘且雾轰化钉饼鉴怔铃撒毯锁挺盔丙屡带猜徐副涉舔近挪檄看藤喜李熙油筑兰菏躯婪瘴男屁墩芍董猖莲盆撑父闻戏撅劳倍妙必抨谓肌行广耿茫崇砒搞邹蔓拍辛喊颊五友骇纪田珐灌舅辙廉企狐保狸玩搁捌亚锨咯罢获地讨疥瘴雷军臀笋货弛眼信砰兔嫁抚箩圈击呆陆伺频惹亿捷很骚耽占谩恳处焕酝候蔽翰颈屯慑馈洞锁浦嘻败韶撼的疑势舟父氯看聊乓足友烯冈阮杠妮肢炭成护幂给宝线翁绊枯送梨汤加奖晤甘杜球斡通诞厘***大近茧襟崔呼邻余氟暂海辑绦间囤匡皋凰童沼沟满晴纲拒砚埔霉梳损膊罩坤牢碍沦腔兄码伤眼笨瞥赞狗备淀侈炔担蝗嘱洗史旨尽潦徐爆苗赖烬眩舌觅远崖仇纷蔫蛾断蓄辕枝谤嗽单勤轩癌檀抵样赛郁等屯碾译粒以琼嫩敢案衷液社温棘急升钞准劈炕臻窗津乍泛书屈乡磕性核勺褥肆毫腮测萤诉症著肩员拘谋炔踏她松还饭窗绘嘛糙矿逸炸呜虞垂并独仰慨瑞嚷权尺酗黎润猜滇恿惦悲闪淑诺熟暗奋狐亲支淘镁滚宽拴颈妙涯洱歇撤恿抱跨档姬圣榴隧暮钦空涕斤浅秋骆屋铀用怪磺撵削处崩累墓席乔辐溢租喂袍茶怂狗蛾彼妆罕稗肘危亿展煌羽泛省肄绸扯锐华空抛百滦银掣支婴久恩恫扼镶扇拭垢而培欢秋蚂存厌么材浅各耶口笨级寓潞刀赋暖茧见追拜迹靠并蒋鹿纽捌痪目荔潭啡沧畜茵卸惦细秆彤晤欣镁拄玩但辣雪迂彭项揽娩灌渣桔青唾癣屈硕饯猖徐绩霸辱携巩若铭荤谗温达花凰懈高睦锚玻门斤阮淹隅速蒸轨席稽酋米呵雅年病苍蔡拄淳铂暇阴屋揩莫腔治疥席淫咀酥休崩杯伪孪疾汝偿让宅释椅士译圾聚崖亲辟碧么攫旭战靡痴昏副线问疮耽矮验值唇仪豹藩煌懦别械妙咎胃身讲晋绣祟埃罪乃正厅蓟笋睦薯误址偶火蜡擎都握隅尔坍对蓑磺亥韵泡儿输故族积徽虚穷仟槽院娇迟戎屈俄帘暗同犊抠骋缮批歼晾灾美南蹋梭屈轻禄弹慧吓分鹃宴船抑换竿强吞注辫锈涧茬醋平美淮矗耘环幼诊谊支吃拇恤长密颧柑互寇喷蔓镊韵观沂祝和窒常卜严冒跃妄适歉匝厂互箍夕追鞋钎披计蜘兜猖佯复驹慎薄曙豫茅陨牌奏烘俄鼓用野焙壳犁酋脚缺憋套汞谊解催轩喧吊疆嘶圭拜苛纺糯菊任凹器庚恤仟忿往凝付娠庐骤墩溉铆养句蜗登肉病窗贩壳庚柞澄骚震靛亚乎辈抛位请拜蜒餐胆扰虹忌仕素种闪郴拔嫁拂划举世反老墩喂西乡伐邯赤鸟环唁击尸逛驻舒戍丽荚谷委抚刑擅梅菌经裴训雕值四祝殉卉碑兢音警奎虎片呈埠帜搏黑拒习各澄孜彰慷暴日鸿橡枝傲灌琢胖恶承漠醇炬戊椒摸黑蹬呆踌馒斥历酷洞茸皂熔惠汕台撞揖羌重吠腆御辜隋莲拂钠哀晚项韵取勾贤台叭涡魁淮鹊皂弱断球撑南耀潞雌殴巴炊该慧挂抿推缴妊批称账骋加激肃蜘踏车其咬江华迫谤种诚瓶膜陌花币缮刨吹哟秘紫际予昂杯乌墒良梦戳燕晴堕犀殴浙披望帅谴孰肘它殃量黎说驶卓锁铲暑蔓声翁龄彪诈桌丑咸蕾服变拈肩辑晰桶呜滋酥披建稗构痒染捎惭竿侗铭蔽蝴西绞捎刃罪鞠漱骑黔熟怨造薛斗政斤钞荤瑞鹃拖庸曲泼角想藕洒巡扼臻档***绕抠捍懈艾誊拂裹偿仓舔着荡麻囊塑和锅非奉滔弗耕风五济疼服调纠迸脖赖
work$

上面是该程序的一次运行结果,随机生成了 1800 个常用汉字中的一级汉字。GB2312 中的 6763 个汉字已经是常用汉字了,超过这个范围的就应该称为生僻字了,主要用于人名、地名等。而 3755 个一级汉字可以说是常用汉字中的常用汉字了。GB2312 中的 3008 个二级汉字相对来说就不那么常用一点了。而且这 3008 个也不全是汉字,还包括偏旁部首。如“钅、讠、氵”等。请看上述运行结果,这随机生成的 1800 个常用汉字中的一级字,你又有多少个不认识的呢?

实际应用

前一段时间,全市金融系统综合业务技术竞赛在我单位举行,我为该竞赛提供技术支持。其中有一项是汉字录入比赛,就要求随机生成 1800 个汉字供参加竞赛的选手录入,录入时间是十分钟。结果我单位的一位在柜面一线工作的女选手夺得了汉字录入项目的冠军,在十分钟内正确录入的汉字达到 1327 个,十分了不起。注意,录入的文本就是上述程序随机生成的汉字,全是单字,没有词组。她使用的是五笔字形输入法。我想如果使用拼音输入的话,应该达不到这个速度。虽然很多人认为五笔字型输入法设计不科学,但是其输入速度还是很快的。

参考资料

  1. 维基百科: GB 2312
  2. 维基百科: GB 18030
  3. 维基百科: 现代汉语通用字表
  4. 中国语言文字网: 《现代汉语常用字表》
  5. 中国语言文字网: 《现代汉语通用字表》
posted on 2012-10-20 19:45  银河  阅读(26303)  评论(15编辑  收藏  举报