我正在运行一个基于Delphi2007构建的遗留应用程序,我们通过在DB中存储字符的2byte Hex代码来处理非英语字符。 在读取时,我们应用char()将这些Hex代码转换为String。
字符串到十六进制(保存到DB之前):
strHex := Format( '%x', [ Byte( strText[ lIndex ] ) shr 4 ] );
DataStr[ lPos ] := strHex[ 1 ];
inc( lPos );
strHex := Format( '%x', [ Byte( strText[ lIndex ] ) and $0F ] );
DataStr[ lPos ] := strHex[ 1 ];
inc( lPos );
//in simple I am saving the Hex code to pcData
Hex to String(从DB读取后):
strText := strText + Chr( StrToInt('$'+ DataStr[lPos] + DataStr[lPos + 1]))
此代码在移至Delphi XE7后开始破解,其中 string 被视为UniCode String,我们显式必须将字符串转换为AnsiString类型。
将下面的字符串转换为十六进制
的ТуцЕфылАшдеук8311
在Delphi 2007中给出:
的 \ D2 \ F3 \ F6 \ C5 \ F4 \ FB \ EB \ C0 \ F8 \ E4 \ E5 \ F3 \ EA8311
在Delphi XE7中给出:
的 \ 22 \ 43 \ 46 \ 1A \ 33 \ 4B \ 4B \ 48 \ 44 \ 42 \ 14 \ 44 \ 49 \ 33 \ 351522
我想知道修改此代码的最佳方法,以便我可以处理遗留数据。
答案 0 :(得分:2)
首先,生成十六进制字符串的简单方法是使用RTL自己的BinToHex()
函数,而不是编写自己的转换代码,例如:
var
...
s: AnsiString;
DataStr: string;
lPos: Integer;
...
begin
...
s := '...';
BinToHex(PAnsiChar(s), @DataStr[lPos], Length(s));
Inc(lPos, Length(s)*2);
...
end;
然后,您可以使用HexToBin()
来反转它。而且由于您正在处理编码的ANSI数据,您可以声明一个AnsiString
变量,该变量与所需的代码页编码具有亲缘关系(在您的情况下,可能是1251),将十六进制代码直接读入该变量,然后分配/将其转换为正常String
并让RTL为您处理转换为Unicode:
type
Win1251String = type AnsiString(1251);
var
...
tmp: Win1251String;
DataStr, strText: string;
lPos: Integer;
...
begin
...
SetLength(tmp, LengthOfHex div 2);
HexToBin(@DataStr[lPos], PAnsiChar(tmp), Length(tmp));
strText := String(tmp);
...
end;
答案 1 :(得分:1)
根据评论,您只需将此数据解码为原生Unicode string
即可。这样做:
string
变量。TEncoding.GetString
对其进行解码。您需要使用正确的代码页TEncoding
创建Encoding := TEncoding.GetEncoding(1251)
类的实例。