我有这个基本代码,应该编码一个字符串,然后将其取回。但是,解码后的文本是垃圾。
procedure TForm5.Button2Click(Sender: TObject);
VAR s1, s2, s3: String;
i: Integer;
begin
for i:= 1 to 200
DO s1:= s1+ char(Random(255));
s1:= EncdDecd.EncodeString(s1);
s3:= EncdDecd.DecodeString(s2);
if s1= s3
then Caption:= 'Equal'
else Caption:= 'Not equal';
end;
更新
如果我做char(Random(128))而不是255!
答案 0 :(得分:5)
问题在于Soap.EncdDecd
单位:
function EncodeString(const Input: string): string;
var
InStr, OutStr: TStringStream;
begin
InStr := TStringStream.Create(Input);
try
OutStr := TStringStream.Create('');
try
EncodeStream(InStr, OutStr);
Result := OutStr.DataString;
finally
OutStr.Free;
end;
finally
InStr.Free;
end;
end;
此代码尚未针对Unicode更新。在不指定编码的情况下使用TStringStream
InStr
是问题所在。如果未指定编码,则ANSI用于解码为字节数组。因此,只能正确解码本地ANSI代码页中的字符。
DecodeString
中的另一个方向犯了同样的错误。
您可以通过创建指定完整Unicode编码的变体来轻松解决此问题。例如:
function EncodeString(const Input: string): string;
var
InStr, OutStr: TStringStream;
begin
InStr := TStringStream.Create(Input, TEncoding.UTF8);
try
OutStr := TStringStream.Create('');
try
EncodeStream(InStr, OutStr);
Result := OutStr.DataString;
finally
OutStr.Free;
end;
finally
InStr.Free;
end;
end;
function DecodeString(const Input: string): string;
var
InStr, OutStr: TStringStream;
begin
InStr := TStringStream.Create(Input);
try
OutStr := TStringStream.Create('', TEncoding.UTF8);
try
DecodeStream(InStr, OutStr);
Result := OutStr.DataString;
finally
OutStr.Free;
end;
finally
InStr.Free;
end;
end;
只要它是完整的Unicode编码,您指定的编码无关紧要,并且您在两个方向上使用相同的编码!
显然应鼓励Embarcadero对其代码进行更改。
此程序演示了此修复程序的工作原理:
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Classes, Soap.EncdDecd;
function EncodeString(const Input: string): string;
var
InStr, OutStr: TStringStream;
begin
InStr := TStringStream.Create(Input, TEncoding.UTF8);
try
OutStr := TStringStream.Create('');
try
EncodeStream(InStr, OutStr);
Result := OutStr.DataString;
finally
OutStr.Free;
end;
finally
InStr.Free;
end;
end;
function DecodeString(const Input: string): string;
var
InStr, OutStr: TStringStream;
begin
InStr := TStringStream.Create(Input);
try
OutStr := TStringStream.Create('', TEncoding.UTF8);
try
DecodeStream(InStr, OutStr);
Result := OutStr.DataString;
finally
OutStr.Free;
end;
finally
InStr.Free;
end;
end;
const
N = 256;
var
i: Integer;
s1, s2: string;
begin
SetLength(s1, N);
for i := 1 to N do
s1[i] := Chr(i-1);
s2 := Soap.EncdDecd.EncodeString(s1);
s2 := Soap.EncdDecd.DecodeString(s2);
Writeln(s1=s2);
s2 := EncodeString(s1);
s2 := DecodeString(s2);
Writeln(s1=s2);
end.
输出:
FALSE TRUE
答案 1 :(得分:0)
快速修复:
ANSI对我来说已经足够了,因为编码后产生的文本必须尽可能短(易于通过电子邮件发送)。所以,我将我的ANSI字符串放入流中并对流进行编码/解码。它奏效了!
耶稣。一些文档(至少一条注释行)本来不错!