回复人: zswang(伴水)(伤心中) (2001-11-21 22:00:29)  得25分 
//很以前玩过
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}const
  cMinGBCByte = 161;                          //最小国标字节
  cMaxGBCByte = 254;                          //最大国标字节function StrToGBC(mStr: string): string; { 返回汉字所对应的区位码 }
begin
  if Length(mStr) = 2 then
    Result := FormatFloat('00', Ord(mStr[1]) - cMinGBCByte + 1)
        + FormatFloat('00', Ord(mStr[2]) - cMinGBCByte + 1)
  else Result := '';
end; { StrToGBC }function GBCToStr(mStr: string): string; { 返回区位码所对应的汉字 }
var
  I, J: Integer;
begin
  I := StrToIntDef(mStr, 0);
  J := I mod 100;
  I := I div 100;
  I := I + cMinGBCByte - 1;
  J := J + cMinGBCByte - 1;
  Result := Chr(I) + Chr(J)
end; { GBCToStr }procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := GBCToStr(Edit1.Text)
end;end.
 
回复人: pazee(耙子) (2001-11-22 10:56:42)  得25分 
汉字编码是认为定义一组汉字的顺序表。
目前常用的gb2312,gb13000,gbk,big5,和unicode.机器内码是汉字编码在计算机里面的具体表示编码,他和汉字编码是有固定对应关系的。
现在window常用的是gbk,他是gb2312的兼容超集。
我们以gb2312为例。
gb2312定义汉字编码分为区码和位码,分别是从1~94.
所以gb2312的编码容量是94*94个汉字,实际上只定义了6763个汉字,
1~9区是特殊字符,包括全角的标点、字母、日文、希腊文、俄文等等
16~87是汉字区。
如果计算机要表示汉字,只能用现有的计算机编码表示,这就有了机内码的概念。
计算机是以字节为单位,只能表示0~255.(asc定义了0~127),所以汉字就用2各连续字节表示一个汉字,为了和0~127的asc分开,采用了从0xa0开始到0xfe的这部分。
就得到了机内码和汉字区位码的对应关系
机内码 = 0xa0 + 区码, 0xa0 + 位码;如果一个汉字的机内码是 0xb0a1那么它对应的区位码就是 0xb0-0xa0= 0x10=16, 0xa1-0xa0= 1,他的区位码是 1601,就是汉字"啊"
反过来一样.这种机内码表示方式有个问题就是一个汉字等于2个asc码,不利于计算字符串长度,还一个问题(在dos下最明显)就是西文造表符的识别。现在的gbk已经比这个复杂了,你理解了gb2312的,gbk就容易了。
现在的趋势是unicode,他是16位内码,包括asc码都扩充到16位了,
他是世界通用的字符集。容量是65534个字符,包含了世界各国的文字。