Delphi 7和解码UTF-8 base64。

时间:2022-04-24 09:39:30

In Delphi 7, I have a widestring encoded with Base64(That I received from a Web service with WideString result) :

在Delphi 7中,我有一个用Base64编码的widestring(我从一个带有widestring结果的Web服务中收到):

PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==

PD94bWwgdmVyc2lvbj0iMS4wIj8 + DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg = =

when I decoded it, that result is not UTF-8:

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

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

But when I decoded it by base64decode.org, result is true :

但当我通过base64decode.org对它进行解码时,结果是正确的:

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

I have use EncdDecd unit for DecodeString function.

我使用了EncdDecd单元来进行解码。

2 个解决方案

#1


4  

The problem you have is that you are using DecodeString. That function, in Delphi 7, treats the decoded binary data as being ANSI encoded. And the problem is that your text is UTF-8 encoded.

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

To continue with the EncdDecd unit you have a couple of options. You can switch to DecodeStream. For instance, this code will produce a UTF-8 encoded text file with your data:

要继续使用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.

Or you could continue with DecodeString, but then immediately decode the UTF-8 text to a WideString. Like this:

或者您可以继续使用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.

If the content of the file can be represented in your application's prevailing ANSI locale then you can convert that WideString to a plain AnsiString.

如果该文件的内容可以在应用程序当前的ANSI语言环境中表示,那么您可以将该WideString转换为普通的AnsiString。

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

However, I really don't think that using ANSI encoded text is going to lead to a very fruitful programming life. I encourage you to embrace Unicode solutions.

然而,我真的不认为使用ANSI编码的文本将会导致一个非常丰富的编程生活。我鼓励您使用Unicode解决方案。

Judging by the content of the decoded data, it is XML. Which is usually handed to an XML parser. Most XML parsers will accept UTF-8 encoded data, so you quite probably can base64 decode to a memory stream using DecodeStream and then hand that stream off to your XML parser. That way you don't need to decode the UTF-8 to text and can let the XML parser deal with that aspect.

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

#2


1  

As an addendum to David Heffernan's awesome answer, and Remy Lebeau's note on how it's broken on Delphi 7, I would like to add a function that will help any developer stuck on Delphi 7.

作为David Heffernan令人惊叹的回答的补充,以及Remy Lebeau关于Delphi 7上的坏消息的说明,我想添加一个功能,可以帮助任何开发人员在Delphi 7上被卡。

Since UTF8Decode() is broken in Delphi 7, I found a function in a forum that solved my problem:

因为在Delphi 7中,UTF8Decode()被破坏,所以我在一个解决我的问题的论坛中找到了一个函数:

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;

So now, you can use DecodeString, and then decode the UTF-8 text to a WideString using this function:

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

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

#1


4  

The problem you have is that you are using DecodeString. That function, in Delphi 7, treats the decoded binary data as being ANSI encoded. And the problem is that your text is UTF-8 encoded.

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

To continue with the EncdDecd unit you have a couple of options. You can switch to DecodeStream. For instance, this code will produce a UTF-8 encoded text file with your data:

要继续使用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.

Or you could continue with DecodeString, but then immediately decode the UTF-8 text to a WideString. Like this:

或者您可以继续使用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.

If the content of the file can be represented in your application's prevailing ANSI locale then you can convert that WideString to a plain AnsiString.

如果该文件的内容可以在应用程序当前的ANSI语言环境中表示,那么您可以将该WideString转换为普通的AnsiString。

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

However, I really don't think that using ANSI encoded text is going to lead to a very fruitful programming life. I encourage you to embrace Unicode solutions.

然而,我真的不认为使用ANSI编码的文本将会导致一个非常丰富的编程生活。我鼓励您使用Unicode解决方案。

Judging by the content of the decoded data, it is XML. Which is usually handed to an XML parser. Most XML parsers will accept UTF-8 encoded data, so you quite probably can base64 decode to a memory stream using DecodeStream and then hand that stream off to your XML parser. That way you don't need to decode the UTF-8 to text and can let the XML parser deal with that aspect.

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

#2


1  

As an addendum to David Heffernan's awesome answer, and Remy Lebeau's note on how it's broken on Delphi 7, I would like to add a function that will help any developer stuck on Delphi 7.

作为David Heffernan令人惊叹的回答的补充,以及Remy Lebeau关于Delphi 7上的坏消息的说明,我想添加一个功能,可以帮助任何开发人员在Delphi 7上被卡。

Since UTF8Decode() is broken in Delphi 7, I found a function in a forum that solved my problem:

因为在Delphi 7中,UTF8Decode()被破坏,所以我在一个解决我的问题的论坛中找到了一个函数:

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;

So now, you can use DecodeString, and then decode the UTF-8 text to a WideString using this function:

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

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