CVCode简繁转换的扩展:GBK与Big5转换
CVCode使用码表对照的方式实现简繁转换,在Unicode盛行的今天仍然是有其现实意义的。
较常见的应用是,企业内有台籍员工,也有大陆员工,而且简体和繁体的OS都有使用,这样在MIS系统中如何保证GB2312、GBK、BIG5都能够正常
CVCode使用码表对照的方式实现简繁转换,在Unicode盛行的今天仍然是有其现实意义的。
较常见的应用是,企业内有台籍员工,也有大陆员工,而且简体和繁体的OS都有使用,这样在MIS系统中如何保证GB2312、GBK、BIG5都能够正常使用,而且BIG5输入的资料在GBK的系统上要显示正常,并且能与GB2312中输入的字符相匹配(查询中,按名称查询是最常见的)。
针对这样的应用,CVCode就提供码表对照的方式,理论上讲,只要定义好码表,就可以真正的让BIG5与GB2312“互通”
但是在CVCode中,只是GB2312与BIG5转换,在GBK输入法流行的今天,GB2312显然不够了。而且BIG5字符集要远远大于GB2312,所以扩展CVCode使其具有GBK与BIG5转换功能势在必行。
GBK的字符范围如下:
GBK字符集范围
分区 高位 低位<
----------------------------------------------
●GBK/1:GB2312非汉字符号: A1~A9 || A1~FE
●GBK/2:GB2312汉字 : B0~F7 || A1~FE
●GBK/3:扩充汉字 : 81~A0 || 40~FE
●GBK/4:扩充汉字 : AA~FE || 40~A0
●GBK/5:扩充非汉字 : A8~A9 || 40~A0
其中1和2就是对应的GB2312字符集。
如何让CVcode支持GBK,有3个问题:
1.判断是否GB码
2.计算字符顺序
3.与原有码表兼容
第一个问题就要修改IsGB如下:
function isGB(value: string): Boolean;
Var
mHigh, mLow : integer;
begin
if (length(value)>=2) then
begin
mHigh := ord(value[1]);
mLow := ord(value[2]);
Result := False;
//●GBK/1:GB2312非汉字符号: A1~A9 || A1~FE
if (mHigh in [$A1..$A9]) and (mLow in [$A1..$FE]) then Result := True;
//●GBK/2:GB2312汉字 : B0~F7 || A1~FE
if (mHigh in [$B0..$F7]) and (mLow in [$A1..$FE]) then Result := True;
//●GBK/3:扩充汉字 : 81~A0 || 40~FE
if (mHigh in [$81..$A0]) and (mLow in [$40..$FE]) then Result := True;
//●GBK/4:扩充汉字 : AA~FE || 40~A0
if (mHigh in [$AA..$FE]) and (mLow in [$40..$A0]) then Result := True;
//●GBK/5:扩充非汉字 : A8~A9 || 40~A0
if (mHigh in [$A8..$A9]) and (mLow in [$40..$A0]) then Result := True;
end
else
Result := true;
{ //这是原来的,只以GB2312为判断依据
if (length(value)>=2) then
begin
if (value[1] <= #161) and (value[1] >= #247) then
Result := false
else
if (value[2] <= #161) and (value[2] >= #254) then
Result := false
else
Result := true
end
else
Result := true;
}
end;
第二个要计算顺序和与原有码表兼容---其实兼容主要也在顺序:
function GBOffset(value: string): integer;
Var
mHigh, mLow : integer;
mGBK1, mGBK2, mGBK3, mGBK4, mGBK5: integer;
begin
{ //这是原来的---
if length(value) >= 2 then
Result := (Ord(value[1]) - $A1) * $5E + (Ord(value[2]) - $A1)
else
Result := -1;
}
Result := -1;
if length(value) >= 2 then
begin
mHigh := ord(value[1]);
mLow := ord(value[2]);
//每个区都有多少个汉字?
//mGBK1 := ($A9 - $A1 + 1) * ($FE - $A1 + 1); // = 846 = $34E
//mGBK2 := ($F7 - $B0 + 1) * ($FE - $A1 + 1); // = 6768 = $1A70
//mGBK3 := ($A0 - $81 + 1) * ($FE - $40 + 1);
//mGBK4 := ($FE - $AA + 1) * ($A0 - $40 + 1);
//mGBK5 := ($A9 - $A8 + 1) * ($A0 - $40 + 1);
mGBK1 := $34E; //846
mGBK1 := mGBK1 + ($B0 - $A9-1) * ($FE - $A1 + 1); //这个是为了和以前的码表兼容
mGBK2 := $1A70; //6768
mGBK3 := $17E0; //6112
mGBK4 := $2035; //8245
mGBK5 := $C2; //194
//●GBK/1:GB2312非汉字符号: A1~A9 || A1~FE
if (mHigh in [$A1..$A9]) and (mLow in [$A1..$FE]) then
Result := (mHigh - $A1) * ($FE - $A1 + 1) + (mLow - $A1)
//●GBK/2:GB2312汉字 : B0~F7 || A1~FE
else if (mHigh in [$B0..$F7]) and (mLow in [$A1..$FE]) then
Result := mGBK1 +
(mHigh - $B0) * ($FE - $A1 + 1) + (mLow - $A1)
//●GBK/3:扩充汉字 : 81~A0 || 40~FE
else if (mHigh in [$81..$A0]) and (mLow in [$40..$FE]) then
Result := mGBK1 + mGBK2 +
(mHigh - $81) * ($FE - $40 + 1) + (mLow - $40)
//●GBK/4:扩充汉字 : AA~FE || 40~A0
else if (mHigh in [$AA..$FE]) and (mLow in [$40..$A0]) then
Result := mGBK1 + mGBK2 + mGBK3 +
(mHigh - $AA) * ($A0 - $40 + 1) + (mLow - $40)
//●GBK/5:扩充非汉字 : A8~A9 || 40~A0
else if (mHigh in [$A8..$A9]) and (mLow in [$40..$A0]) then
Result := mGBK1 + mGBK2 + mGBK3 + mGBK4 +
(mHigh - $A8) * ($A0 - $40 + 1) + (mLow - $40);
end
end;