原由
一日上机玩的时候,一同学问起如何在C#中Console.ReadLine()[0]扑获的字符转化为Acsii码,后来解决拉
不过我却留心起,那能不能用Acsii码的原理来扑获汉字的拼音呢?
汉字编码原理
汉字从哪里来的呢?是不是有个后台数据表,其中存放了所需要的所有汉字?
1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准: GB2312-80《信息交换用汉字编码字符集》基本集,简称GB2312,这个字符集是我国中文信息处理技术的发展基础,也是国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,简称GB18030,编程时如果涉及到编码和本地化的朋友应该对GB18030很熟悉。这是是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,同时也是未来我国计算机系统必须遵循的基础性标准之一。
目前在中文WINDOWS操作系统中,.NET编程中默认的的代码页就是GB18030简体中文。但是事实上如果生成中文汉字验证码只须要使用GB2312字符集就已经足够了。字符集中除了我们平时大家都认识的汉字外,也包含了很多我们不认识平时也很少见到的汉字。如果生成中文汉字验证码中有很多我们不认识的汉字让我们输入,对于使用拼音输入法的朋友来说可不是好事,五笔使用者还能勉强根据汉字的长相打出来,呵呵!所以对于GB2312字符集中的汉字我们也不是全都要用
中文汉字字符可以使用区位码来表示.
有兴趣的可以去看看这里:
http://www.lianping.gov.cn/zhaofang/computer/office/gb2312.htm
1980年,为了使每一个汉字有一个全国统一的代码,我国颁布了第一个汉字编码的国家标准: GB2312-80《信息交换用汉字编码字符集》基本集,简称GB2312,这个字符集是我国中文信息处理技术的发展基础,也是国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,简称GB18030,编程时如果涉及到编码和本地化的朋友应该对GB18030很熟悉。这是是我国继GB2312-1980和GB13000-1993之后最重要的汉字编码标准,同时也是未来我国计算机系统必须遵循的基础性标准之一。
目前在中文WINDOWS操作系统中,.NET编程中默认的的代码页就是GB18030简体中文。但是事实上如果生成中文汉字验证码只须要使用GB2312字符集就已经足够了。字符集中除了我们平时大家都认识的汉字外,也包含了很多我们不认识平时也很少见到的汉字。如果生成中文汉字验证码中有很多我们不认识的汉字让我们输入,对于使用拼音输入法的朋友来说可不是好事,五笔使用者还能勉强根据汉字的长相打出来,呵呵!所以对于GB2312字符集中的汉字我们也不是全都要用
中文汉字字符可以使用区位码来表示.
有兴趣的可以去看看这里:
http://www.lianping.gov.cn/zhaofang/computer/office/gb2312.htm
Net程序处理汉字编码原理分析
在.Net中可以使用System.Text来处理所有语言的编码。在System.Text命名空间中包含众多编码的类,可供进行操作及转换。其中的Encoding类就是重点处理汉字编码的类。通过在.NET文档中查询Encoding类的方法我们可以发现所有和文字编码有关的都是字节数组,其中有两个很好用的方法:
Encoding.GetBytes ()方法将指定的 String 或字符数组的全部或部分内容编码为字节数组
Encoding.GetString ()方法将指定字节数组解码为字符串。
没错我们可以通过这两个方法将汉字字符编码为字节数组,同样知道了汉字GB2312的字节数组编码也就可以将字节数组解码为汉字字符。通过对“好”字进行编码为字节数组后
Encoding gb=System.Text.Encoding.GetEncoding("gb2312");
object[] bytes=gb.Encoding.GetBytes ("好");
发现得到了一个长度为2的字节数组bytes,使用
string lowCode = System.Convert.ToString(bytes[0], 16); //取出元素1编码内容(两位16进制)
string hightCode = System.Convert.ToString(bytes[1], 16);//取出元素2编码内容(两位16进制)
代码
新建一类文件ChineseCodning.cs
//------------------------------------------------------------------------------ // // This code was generated by SharpDevelop. // Runtime Version: 1.1.4322.573 // // 作者:张健滢 // 时间:2005/12/17 // //------------------------------------------------------------------------------ namespace Demo { using System; using System.Text; /// /// 中文编码类 /// 获得拼音首字母 /// /// /// created by - 张健滢 /// created on - 2005-12-17 21:43:01 /// public sealed class ChineseCodning : object { /// /// 空构造函数 /// /// public ChineseCodning(){ } public char getPinYin(string Source){ int keyNumber=getCodeNumber(Source); if (keyNumber>=getCodeNumber("啊") && keyNumber<=getCodeNumber("澳")) return 'a'; else if (keyNumber>=getCodeNumber("芭") && keyNumber<=getCodeNumber("怖")) return 'b'; else if (keyNumber>=getCodeNumber("擦") && keyNumber<=getCodeNumber("错")) return 'c'; else if (keyNumber>=getCodeNumber("搭") && keyNumber<=getCodeNumber("堕")) return 'd'; else if (keyNumber>=getCodeNumber("蛾") && keyNumber<=getCodeNumber("贰")) return 'e'; else if (keyNumber>=getCodeNumber("发") && keyNumber<=getCodeNumber("咐")) return 'f'; else if (keyNumber>=getCodeNumber("噶") && keyNumber<=getCodeNumber("过")) return 'g'; else if (keyNumber>=getCodeNumber("哈") && keyNumber<=getCodeNumber("祸")) return 'h'; else if (keyNumber>=getCodeNumber("击") && keyNumber<=getCodeNumber("骏")) return 'j'; else if (keyNumber>=getCodeNumber("喀") && keyNumber<=getCodeNumber("阔")) return 'k'; else if (keyNumber>=getCodeNumber("垃") && keyNumber<=getCodeNumber("络")) return 'l'; else if (keyNumber>=getCodeNumber("妈") && keyNumber<=getCodeNumber("穆")) return 'm'; else if (keyNumber>=getCodeNumber("拿") && keyNumber<=getCodeNumber("诺")) return 'n'; else if (keyNumber>=getCodeNumber("哦") && keyNumber<=getCodeNumber("沤")) return 'o'; else if (keyNumber>=getCodeNumber("啪") && keyNumber<=getCodeNumber("瀑")) return 'p'; else if (keyNumber>=getCodeNumber("期") && keyNumber<=getCodeNumber("群")) return 'q'; else if (keyNumber>=getCodeNumber("然") && keyNumber<=getCodeNumber("弱")) return 'r'; else if (keyNumber>=getCodeNumber("撒") && keyNumber<=getCodeNumber("所")) return 's'; else if (keyNumber>=getCodeNumber("塌") && keyNumber<=getCodeNumber("唾")) return 't'; else if (keyNumber>=getCodeNumber("挖") && keyNumber<=getCodeNumber("误")) return 'w'; else if (keyNumber>=getCodeNumber("昔") && keyNumber<=getCodeNumber("迅")) return 'x'; else if (keyNumber>=getCodeNumber("压") && keyNumber<=getCodeNumber("轧")) return 'y'; else if (keyNumber>=getCodeNumber("铡") && keyNumber<=getCodeNumber("座")) return 'z'; return '*'; } /// /// 获得16进制编码 /// /// 返回汉字16进制区位码 public string getHexEncoding(string Source){ isChinese(Source); Encoding gb=System.Text.Encoding.GetEncoding("gb2312"); byte[] bytes=gb.GetBytes (Source); string lowCode = System.Convert.ToString(bytes[0],16); string hightCode = System.Convert.ToString(bytes[1],16); return lowCode+hightCode; } /// /// 获得中国汉字的对应16进制区位码的整数值 /// /// 16进制区位码的整数值 private static int getCodeNumber(string Source){ ChineseCodning target =new ChineseCodning(); return Convert.ToInt32(target.getHexEncoding(Source),16); } /// /// 判断是否是中国汉字 /// /// private static void isChinese(string Source){ //判断string长度 if (Source.Length!=1) throw new Exception("输入过多或不够,请保证只要输入一个汉字"); Encoding gb=System.Text.UTF8Encoding.GetEncoding("gb2312"); byte[] bytes=gb.GetBytes (Source); //判断是否是双字节 if (bytes.Length!=2) throw new Exception("输入过多或不够,请保证只要输入一个汉字"); //判断汉字的范围是否是符合GB2312-80区位编码规范 string lowCode = System.Convert.ToString(bytes[0],16); string hightCode = System.Convert.ToString(bytes[1],16); int k= Convert.ToInt32(lowCode+hightCode,16); ChineseCodning traget= new ChineseCodning(); if (k<45217 || k>55289 ) throw new Exception("输入的汉字不符合GB2312-80区位编码规范"); } } } |
在主函数中如此调用:
public static void Main(string[] args) { ChineseCodning c=new ChineseCodning(); Console.WriteLine(c.getPinYin("张")); //获得区位码 Console.WriteLine(c.getHexEncoding("张")); Console.WriteLine(c.getPinYin("健")); Console.WriteLine(c.getPinYin("周")); //"滢"字不在GB2312-80规范之内 try{ Console.WriteLine(c.getPinYin("滢")); }catch(Exception e) { Console.WriteLine("出错:/"滢/"字不在GB2312-80规范之内"); } } |
暂时我还没有找到扩充字符的资料,所以有一部分字无法查到,不过没关系!