Delphi 7和解码UTF-8 base64

时间:2015-08-31 08:30:39

标签: delphi delphi-7

在Delphi 7中,我有一个使用Base64编码的宽字符串(我从具有WideString结果的Web服务收到):

PD94bWwgdmVyc2lvbj0iMS4wIj8 + DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg ==

当我解码它时,结果不是UTF-8:

<?xml version="1.0"?>
<string>طھط³طھ</string>

但是当我用base64decode.org解码它时,结果为真:

<?xml version="1.0"?>
<string>تست</string>

我使用EncdDecd单元作为DecodeString函数。

2 个答案:

答案 0 :(得分:5)

您遇到的问题是您使用的是DecodeString。在Delphi 7中,该函数将解码的二进制数据视为ANSI编码。问题是您的文本是UTF-8编码的。

要继续使用EncdDecd单元,您有几个选择。您可以切换到DecodeStream。例如,此代码将生成包含您的数据的UTF-8编码文本文件:

{$APPTYPE CONSOLE}

uses
  Classes,
  EncdDecd;

const
  Data = 'PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==';

var
  Input: TStringStream;
  Output: TFileStream;

begin
  Input := TStringStream.Create(Data);
  try
    Output := TFileStream.Create('C:\desktop\out.txt', fmCreate);
    try
      DecodeStream(Input, Output);
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end.

或者您可以继续DecodeString,但随后立即将UTF-8文本解码为WideString。像这样:

{$APPTYPE CONSOLE}

uses
  Classes,
  EncdDecd;

const
  Data = 'PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==';

var
  Utf8: AnsiString;
  wstr: WideString;

begin
  Utf8 := DecodeString(Data);
  wstr := UTF8Decode(Utf8);
end.

如果文件的内容可以在您的应用程序的主流ANSI区域设置中表示,那么您可以将WideString转换为普通AnsiString

var
  wstr: WideString;
  str: string; // alias to AnsiString
....
wstr := ... // as before
str := wstr;

但是,我真的不认为使用ANSI编码的文本会带来非常富有成效的编程生活。我鼓励你接受Unicode解决方案。

根据解码数据的内容判断,它是XML。通常将其传递给XML解析器。大多数XML解析器都接受UTF-8编码数据,因此您很可能使用DecodeStream将base64解码为内存流,然后将该流传递给XML解析器。这样您就不需要将UTF-8解码为文本,并且可以让XML解析器处理该方面。

答案 1 :(得分:1)

作为David Heffernan的精彩答案的附录,以及Remy Lebeau关于它如何在Delphi 7上被打破的说明,我想添加一个功能,可以帮助任何开发人员坚持德尔福7。

由于UTF8Decode()在Delphi 7中被破坏,我在forum中发现了一个解决了我的问题的函数:

function UTF8ToWideString(const S: AnsiString): WideString;
var
  BufSize: Integer;
begin
  Result := '';
  if Length(S) = 0 then Exit;
  BufSize := MultiByteToWideChar(CP_UTF8, 0, PAnsiChar(S), Length(S), nil, 0);
  SetLength(result, BufSize);
  MultiByteToWideChar(CP_UTF8, 0, PANsiChar(S), Length(S), PWideChar(Result), BufSize);
end;

现在,您可以使用DecodeString,然后使用此函数将UTF-8文本解码为WideString

begin
  Utf8 := DecodeString(Data);
  wstr := UTF8ToWideString(Utf8);
end.