汉字编码相关知识收集


字符编码:字符编码就是以二进制的数字来对应字符集的字符,目前用得最普遍的字符集是ANSI,对应ANSI字符集的二进制编码就称为ANSI码,DOS和Windows系统都使用了ANSI码,但在系统中使用的字符编码要经过二进制转换,称为系统内码。
  汉字内码:ANSI码是单一字节(8位二进制数)的编码集,最多只能表示256个字符,不能表示众多的汉字字符,各个国家和地区在ANSI码的基础上又设计了各种不同的汉字编码集,以能够处理大数量的汉字字符。这些编码使用单字节来表示ANSI的英文字符(即兼容ANSI码),使用双字节来表示汉字字符。由于一个系统中只能有一种汉字内码,不能识别其它汉字内码的字符,造成了交流的不便。
  GB码:GB码是1980年国家公布的简体汉字编码方案,在大陆、新加坡得到广泛的使用,也称国标码。国标码对6763个汉字集进行了编码,涵盖了大多数正在使用的汉字。
  GBK码:GBK码是GB码的扩展字符编码,对多达2万多的简繁汉字进行了编码,简体版的Win95和Win98都是使用GBK作系统内码。
  BIG5码:BIG5码是针对繁体汉字的汉字编码,目前在台湾、香港的电脑系统中得到普遍应用。
  HZ码:HZ码是在Internet上广泛使用的一种汉字编码。
  ISO-2022CJK码:IOS-2022是国际标准组织(ISO)为各种语言字符制定的编码标准。采用二个字节编码,其中汉语编码称ISO-2022 CN,日语、韩语的编码分别称JP、KR。一般将三者合称CJK码。目前CJK码主要在Internet网络中使用。
  Unicode码:Unicode码也是一种国际标准编码,采用二个字节编码,与ANSI码不兼容。目前,在网络、Windows系统和很多大型软件中得到应用。
  内码转换:由于历史、地区原因,有时一种文字会出现多种编码方案,特别是汉字。由于不同于系统内码的字符不能在该系统中正常显示,必须要进行字符的内码转换,即将非系统内码的字符转换为系统可以识别的内码字符。南极星就是这样的优秀软件,其它如四通利方、MagicWin98、两岸通、汉字通等都是这样的内码转换工具。

什么是ANSI
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。
不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。
不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。

 汉字编码问题
汉字编码问题
一、GB2312-80介绍
GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集--基本集》,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定"对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示",习惯上称第一个字节为"高字节",第二个字节为"低字节"。GB2312-80包含了大部分常用的一、二级汉字,和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是0xa1-0xfe;汉字从0xb0a1开始,结束于0xf7fe。
GB2312将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。故而GB2312最多能表示6763个汉字。
GB2312的编码范围为2121H-777EH,与ASCII有重叠,通行方法是将GB码两个字节的最高位置1以示区别。

二、GB2312-80的扩展
GBK是GB2312-80的扩展,是向上兼容的。它包含了20902个汉字,其编码范围是0x8140-0xfefe,剔除高位0x80的字位。其所有字符都可以一对一映射到Unicode2.0。
GB18030-2000(GBK2K)在GBK的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。GBK2K从根本上解决了字位不够,字形不足的问题。它有几个特点:
l         它并没有确定所有的字形,只是规定了编码范围,留待以后扩充。
l         编码是变长的,其二字节部分与GBK兼容;四字节部分是扩充的字形、字位,其编码范围是首字节0x81-0xfe、二字节0x30-0x39、三字节0x81-0xfe、四字节0x30-0x39。
l         它的推广是分阶段的,首先要求实现的是能够完全映射到Unicode3.0标准的所有字形。
l         它是国家标准,是强制性的。
l         现在还没有任何一个操作系统或软件实现了GBK2K的支持,这是现阶段和将来汉化的工作内容。
三、Unicode编码
国际标准组织于1984年4月成立ISO/IECJTC1/SC2/WG2工作组,针对各国文字、符号进行统一性编码。1991年美国跨国公司成立UnicodeConsortium,并于1991年10月与WG2达成协议,采用同一编码字集。目前Unicode是采用16位编码体系,其字符集内容与ISO10646的BMP(BasicMultilingualPlane)相同。Unicode于1992年6月通过DIS(DrafInternationalStandard),目前版本V2.0于1996公布,内容包含符号6811个,汉字20902个,韩文拼音11172个,造字区6400个,保留20249个,共计65534个。
随着国际互联网的迅速发展,要求进行数据交换的需求越来越大,不同的编码体系越来越成为信息交换的障碍,而且多种语言共存的文档不断增多,单靠代码页已很难解决这些问题,于是UNICODE应运而生。
UNICODE有双重含义,首先UNICODE是对国际标准ISO/IEC10646编码的一种称谓(ISO/IEC10646是一个国际标准,亦称大字符集,它是ISO于1993年颁布的一项重要国际标准,其宗旨是全球所有文种统一编码),另外它又是由美国的HP、Microsoft、IBM、Apple等大企业组成的联盟集团的名称,成立该集团的宗旨就是要推进多文种的统一编码。
UNICODE同现在流行的代码页最显著不同点在于:UNICODE是两字节的全编码,对于ASCII字符它也使用两字节表示。代码页是通过高字节的取值范围来确定是ASCII字符,还是汉字的高字节。如果发生数据损坏,某处内容破坏,则会引起其后汉字的混乱。UNICODE则一律使用两个字节表示一个字符,最明显的好处是它简化了汉字的处理过程。
UNICODE使用平面来描述编码空间,每个平面分为256行,256列,相对于两字节编码的高低两个字节。
UNICODE的第一个平面,称为BasicMultilingualPlane(基本多文种平面),简称BMP,由于BMP仅用两个字节表示,所以倍受青睐。 

其中A_ZONE为拼音文字编码区,拉丁文、阿拉伯文、日文的平假名及片假名等都在此区编码。CJKExtensionA和CJK为汉字区域共计27487个汉字。Y1即彝文,位于O-ZONE保留待将来使用。Hangul即韩文。EUDC为用户私有区,用户可以根据需要自己定义此区的编码。R-ZONE为限制使用区,一些兼容字符、特殊字符均放在此区。

UNICODE定义BMP中的D800-DFFF为代理区(SurrogateZone),其中D800-D8FF为高半代理(highsurrogate),DC00-DFFF为低半代理(lowsurrogate)。从两个区域分别取一个编码,组成一个4字节的代理对来表示一个编码字符,此即为UTF-16。利用UTF-16机制,UNICODE扩充了1024*1024个字符,相应于OO-OF平面,并且将02平面分配给了CJKExtensionB。Microsoft在Windows2000已实现了UTF-16。

四、大五码(Big5)
如不去考虑特殊符号,及后来的七个扩充字,TW-BIG5 的排序方式如下。将所有的字分成两大群:常用字区与次常用字区,每一个字区分别用笔画来排序,同一个笔画的字,依部首来排。TW-BIG5 每个字由两个字节组成,其第一字节编码范围为0xA1~0xF9,第二字节编码范围为0x40~0x7E与0xA1~0xFE,总计收入13868个字 (包括5401个常用字、7652 个次常用字、7个扩充字、以及808个各式符号),其中可以大致划分为以下几个字区:

五、如何判断一个汉字是big5或是gb
大陆电脑中的汉字多以GB2312标准进行编码,简称GB码或国标码,共定义6763汉字,编码如下:
第一字节,行码0xA1-0xFE,第二节字,列码0xA1-0xFE,每行94个汉字。其中,1-15行(A1-AF)全角字母、符号;16-55行(B0-CF)以拼音为序的一级汉字3755字;56-87行(D0-F7)以部首为序的二级汉字3008字。例如:GB码16行1列表示"啊"字,编码为0xB0A1。
港台电脑中的汉字则多以BIG5编码,共定义了13053汉字,汉字部分均以部首为序,编码如下:
第一节字,行码0xA1-0xFE,第二节字,列码0x40-0x7E,0xA1-0xFE,每行157个汉字;其中,1-3/38-40行(A1-A3,C6-C8)全角字母、符号,4-39行(A4-C6)一级汉字5401字,41-89行(C9-F9)二级汉字7652字。例如:BIG5码16行121列同样表示"啊"字,编码为0xB0DA。
GBK又称GB扩展编码或GB13000,就是这样的一个汉字编码,它是是在兼容GB码的基础上,将GB码中不存在的ISO10646.1汉字,按Unicode编码顺序进行重新编码。其编码空间包含几个子集,其中GBK/2就是GB码汉字;各子集的编码情况见下表。
子集编码范围编码空间编码字数
GBK/10xA1A1-0xA9FE846717
GBK/20xB0A1-0xF7FE6,7686,763
GBK/30x8140-0xA0FE6,0806,080
GBK/40xAA40-0xFEA08,1608,160
GBK/50xA840-0xA9A0192166
EUDC/10xAAA1-0xAFFE564用户定义1
EUDC/20xF8A1-0xFEFE658用户定义2
EUDC/30xA140-0xA7A0672用户定义3
一般是这样辨别的:
1、GBcode的内码的两个字节都是从A0H-FEH之间的;
2、BIGcode的内码的第一个字节是80H-FFH,第二个字节是00H-FFH;
你要浏览全文,看看是否有第二个字节是小于7FH的汉字,如果有的话,一般是BIGcode的。当然也有特殊情况,不过非常少见的。
判断一段文字中是否含有BIG5码汉字,可用做内码的自动识别
返回True表示包含BIG5码
返回False表示不含BIG5码,这段文字一般可认为是GB码
FunctionCheckBIG(strSourceAsString)AsBoolean
DimidxAsLong
DimByteTemp()AsByte
CheckBIG=False
Foridx=1ToLen(strSource)
ByteTemp=StrConv(Mid(strSource,idx,1),vbFromUnicode)
IfUBound(ByteTemp)>0Then
IfByteTemp(1)>=64AndByteTemp(1)<=126Then
CheckBIG=True
ExitFor
EndIf
EndIf
Next
EndFunction


//获得汉字的区位码
  byte[] array = new byte[2];
  array = System.Text.Encoding.Default.GetBytes("啊");
  
  int i1 = (short)(array[0] - '/0');
  int i2 = (short)(array[1] - '/0');
  
  //unicode解码方式下的汉字码
  array = System.Text.Encoding.Unicode.GetBytes("啊");
  i1 = (short)(array[0] - '/0');
  i2 = (short)(array[1] - '/0');
  
  //unicode反解码为汉字
  string str = "4a55";
  string s1 = str.Substring(0,2);
  string s2 = str.Substring(2,2);
  
  int t1 = Convert.ToInt32(s1,16);
  int t2 = Convert.ToInt32(s2,16);
  
  array[0] = (byte)t1;
  array[1] = (byte)t2;
  
  string s = System.Text.Encoding.Unicode.GetString(array);
  
  //default方式反解码为汉字
  array[0] = (byte)196;
  array[1] = (byte)207;
  s = System.Text.Encoding.Default.GetString(array);
  
  //取字符串长度
  s = "iam方枪枪";
  int len = s.Length;//will output as 6
  byte[] sarr = System.Text.Encoding.Default.GetBytes(s);
  len = sarr.Length;//will output as 3+3*2=9
  
 
//获取内码
 string GetNeiMa(string text)
  {
   string s="";  
   for(int i=0;i<text.Length;i++)
   {
    int tmp=(int)text[i];
   
    if(tmp>0xA0)//汉字
    {     
     byte[] b=System.Text.Encoding.GetEncoding(936).GetBytes(text[i].ToString());
     s+="//'"+b[0].ToString("x2") + "//'"+b[1].ToString("x2");
     
    }
    else
     s+=text[i];
   }
   return s;
  }
  
  
  //由内码得到汉字(采用GB2312编码)  
  private string GetGB2312(string s)
  {
   System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
   byte[] hz=converter.GetBytes(s); 
   MessageBox.Show(s.Replace("//'",""));
   string  gb=System.Text.Encoding.GetEncoding("GB2312").GetString(hz);
   return gb;
  }

//UTF-8与Gb2312的转换
encoding gb2312 = encoding.getencoding("gb2312");
response.contentencoding = gb2312;
在非asp.net 应用中,可能你读到的数据是utf-8编码,但是你要转换为gb2312编码,则可以参考以下代码:

string utfinfo = "document.write(/"alert('你好么??');/");";
string gb2312info = string.empty;

encoding utf8 = encoding.utf8;
encoding gb2312 = encoding.getencoding("gb2312");

/ convert the string into a byte[].
byte[] unicodebytes = utf8.getbytes(utfinfo);
/ perform the conversion from one encoding to the other.
byte[] asciibytes = encoding.convert(utf8, gb2312, unicodebytes);
          
/ convert the new byte[] into a char[] and then into a string.
/ this is a slightly different approach to converting to illustrate
/ the use of getcharcount/getchars.
char[] asciichars = new char[gb2312.getcharcount(asciibytes, 0, asciibytes.length)];
gb2312.getchars(asciibytes, 0, asciibytes.length, asciichars, 0);
gb2312info = new string(asciichars); 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值