其它的不说了,就拿一个最为明显的GB2BIG5,在网上曾一度流传着一份Delphi的代码GB2BIG5.pas,并在开源的EBOOK当中也有使用。而里面竟有明显的错误(不管如何去设想都无法设想出那是笔误),在GB2312当中高位的范围是161~247(包括161和247),但是上面判断时使用(Value[1]>#161) and (Value[1]<#247),而GB2312码表范围是:
============================
GB2312
范围: 0xA1A1 - 0xFEFE
汉字范围: 0xB0A1 - 0xF7FE 
============================
那不是明显的错误?若不是有意,谁会去写如此判定式?而这个转换就使得部分汉字(包括符号)转换成了乱码。下面是开源版的SRM阅读器转码单元的片断(当然这个是阅读工具,汉字转码不属于他自己的范畴了,此处只做引用),我们来看看GB2312里面的"。",这个应该是0xA1A3,那么我们要转换成BIG5应该是0xA10C,但是若断做非GB2312编码寻就是保留做0xA1A3,显示就大致类似于"("。有人说这只是个符号,那我们看"啊"字(0xB0A1),这应该是一个GB2312编码的字吧?同样的低位值==0xA1,照公式结果,不转。保留0xB0A1,则到了BIG5就变成了"陛"。这转出来的BIG5码如何去读?所以只能说明在发布时被人动了手脚。这还是比较明显的,谁又能清楚八千多个GB2312码、一万四千多个BIG5码里面又有没改过个别甚至数个文字编码呢?无法想象。
======================================
function GbToBig(Buf:pointer):pointer;
type
  pWord=^word;
var
  p,pp:^Byte;
begin
  p:=Buf;
  pp:=pointer(integer(p)+1);
  while pp^<>0 do
  begin
    if (p^>161) and (pp^>161) then //当"。"($A1A3)时,p^=161,false=(p^>161),不转换
    begin                          //当"啊"($B0A1)时,pp^=161,false=(pp^>161),不转换
      pWord(p)^:=GbOrder[(p^-161)*94+pp^-161];
      Inc(p);Inc(p);
    end
    else
    begin
      Inc(p);
    end;
    pp:=pointer(integer(p)+1);
  end;
  Result:=Buf;
end;
======================================

解决方案 »

  1.   

    to jackasm() 
    不管如何的水平,一个是判断BIG5码,一个是判断GB2312码的,为什么BIG5的还复杂都没错,偏偏GB2312的错了?
      

  2.   

    關注, 我好象也有一份GB2BIG5.pas, 今晚檢查下!!
      

  3.   

    太正常了
    我从网上下的东西没有不需要改的
    甚至是玩mud的机器人*.mud
    现在还有人知道mud不?
    呵呵
      

  4.   

    先说如下需要修改的Delphi某一版本的GB2BIG的代码:
    ===============================================
    //修改过的代码function isGB(Value: string) : Boolean;
    begin
    Result := (Length(Value) < 2) or
      (((Value[1] >= #161) and (Value[1] <= #247)) and
       ((Value[2] >= #161) and (Value[2] <= #254)));
    end;
    ===============================================
    //如果没记错的话,这是原来的代码
    function isGB(Value: string) : Boolean;
    begin
    Result := (Length(Value) < 2) or
      (((Value[1] > #161) and (Value[1] < #247)) and
       ((Value[2] >= #161) and (Value[2] <= #254)));
    end;
    ===============================================CB版
    ===============================================
    bool isGB(AnsiString Value)
    {
       
       return (Value.Length() < 2) ||
      (((Value.c_str[1-1] >= 161) && (Value.c_str[1-1] <= 247)) &&
       ((Value.c_str[2-1] >= 161) and (Value.c_str[2-1] <= 254)));
    }
    ===============================================
    其实就是最位与161比较时是用大于等于(>=)做比较,与247比较时是用小于等于(<=)做比较,也就是应该包含(247和161);低位同样也是包含了(161和254)。
    其它的依此修正,文字就不清楚有没错误了。
      

  5.   

    //某一Delphi版本GB2BIG的源代码
    //码表就不贴出来了,以免误导
    //另外AutoGB和AutoBIG5这没有绝对的
    //只能是大体判断是否应该归于BIG5
    //否则还需要词汇表才可以判断得更为准确
    //---------------------------------------------------
    function WordToString(Value: Word) : string;
    begin
    Result := Chr(Hi(Value)) + Chr(Lo(Value));
    end;function GBOffset(Value: string) : integer;
    begin
    Result := -1; if Length(Value) >= 2 then
    Result := (Ord(Value[1]) - 161) * 94 + Ord(Value[2]) - 161;
    end;function BIG5Offset(Value: string) : integer;
    begin
    Result := -1; if Length(Value) >= 2 then
    begin
    if Ord(Value[2]) <= 126 then
    Result := (Ord(Value[1]) - 161) * 157 + Ord(Value[2]) - 64
    else
    Result := (Ord(Value[1]) - 161) * 157 + Ord(Value[2]) - 98;
    end;
    end;function isGB(Value: string) : Boolean;
    begin
    Result := (Length(Value) < 2) or
      (((Value[1] >= #161) and (Value[1] <= #247)) and
       ((Value[2] >= #161) and (Value[2] <= #254)));
    end;function isBIG5(Value: string) : Boolean;
    begin
    Result := (Length(Value) >= 2) and
      ((Value[1] >= #129) and (Value[1] <= #254)) and
      (((Value[2] >= #64) and (Value[2] <= #126)) or ((Value[2] >= #161) and (Value[2] <= #254)));
    end;function VerifyBIG5(Value : string) : boolean;
    var
    nLeng, nIndex : integer;
    strTempStr : string[2];
    nGBCount, nCount : integer;
    begin
    nLeng := Length(Value);
    nIndex := 1; nGBCount := 0;
    nCount := nLeng; while nIndex <= nLeng do
    begin
    strTempStr := Value[nIndex] + Value[nIndex + 1]; if isGB(strTempStr) then
    begin
    inc(nGBCount, 2);
    inc(nIndex);
    end
    else
    begin
    if Value[nIndex] > #127 then
    inc(nIndex)
    else
                 dec(nCount);
    end; inc(nIndex);
    end; Result := (nGBCount * 1.4 < nCount);
    end;function GBtoBIG5(Value: string) : string;
    var
    nLeng, nIndex : integer;
    strTempStr : string[2];
    nOffset : integer;
    strOutput : string;
    begin
    strOutput := '';
    nLeng := Length(Value);
    nIndex := 1; while nIndex <= nLeng do
    begin
    strTempStr := Value[nIndex] + Value[nIndex + 1]; if isGB(strTempStr) then
    begin
    nOffset := GBOffset(strTempStr);
    if (nOffset >= 0) and (nOffset <= 8177) then
    begin
    strOutput := strOutput + WordToString(GBOrder[nOffset]);
    inc(nIndex);
    end
    else
    strOutput := strOutput + Value[nIndex];
    end
    else
    strOutput := strOutput + Value[nIndex] ; inc(nIndex);
    end; Result := strOutput;
    end;function BIG5toGB(Value: string) : string;
    var
    nLeng, nIndex : integer;
    strTempStr : string[2];
    strOutput : string;
    nOffset : integer;
    begin
    strOutput := '';
    nLeng := Length(Value);
    nIndex := 1; while nIndex <= nLeng do
    begin
    strTempStr := Value[nIndex] + Value[nIndex + 1]; if isBIG5(strTempStr) then
    begin
    nOffset := BIG5Offset(strTempStr);
    if (nOffset >= 0) and (nOffset <= 14757) then
    begin
    strOutput := strOutput + WordToString(BIG5Order[nOffset]);
    inc(nIndex);
    end
    else
    strOutput := strOutput + Value[nIndex];
    end
    else
    strOutput := strOutput + Value[nIndex]; inc(nIndex);
    end; Result := strOutput;
    end;function AutoGB(Value : string) : string;
    begin
    if VerifyBIG5(Value) then
    Result := BIG5toGB(Value)
    else
    Result := Value;
    end;function AutoBIG5(Value : string) : string;
    begin
    if VerifyBIG5(Value) then
    Result := Value
    else
    Result := GBtoBIG5(Value);
    end;
      

  6.   

    这样开源不道德!>>>>太正常了
    我从网上下的东西没有不需要改的
    甚至是玩mud的机器人*.mud
    现在还有人知道mud不?
    呵呵>>> hellolongbin你也玩MUD呀?现在还玩吗?曾经迷上这东西一年多时间,真到XMxyj OVER为止!呵呵
      

  7.   

    uuuuuuuuuuuuuuuuuuuuppppppppppppppppppppppppppp