2015-08-31 497 views
0

在Delphi 7,我有Base64编码(即我从与WideString的结果的Web服务接收到的)一个WideString的:Delphi 7中和解码UTF-8的base64

PD94bWwgdmVyc2lvbj0iMS4wIj8 + DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg ==

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

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

但是当我通过base64decode.org解码的话,结果为真:

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

我对DecodeString函数使用EncdDecd单元。

+0

相关问题:[如何使用EncdDec库编码字符串](http://stackoverflow.com/questions/21883152/how-to-encode-strings-with-encddec-library) – fantaghirocco

回答

4

您遇到的问题是您使用的是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解析器处理这方面的问题。

+0

+1这是值得的他说UTF-8是一种Unicode解决方案,即使是老版本的Delphi也是如此,因为OP仍在使用。 HTTP://www.utf8everywhere。org /对于简单的过程,使用WideString是解决方案;但它具有性能成本(因为BSTR内存分配非常差)。您可以使用专用的UTF-8函数或类,如果需要的话,可以使用Delphi 7进行更大型的项目。 –

+0

@ArnaudBouchez同意。我当然不是暗示UTF-8不是Unicode。 –

+2

请注意,UTF8Decode()'(和'UTF8Encode()')在Delphi的旧版本(包括v7)中被破坏了。例如,它不是一个完整的UTF-8实现,它不能处理3字节以上的UTF-8序列。它最终在D2009中得到了修复(通过摆脱手动的UTF-8实现并让操作系统进行编码/解码)。 –

1

作为附录大卫赫弗南的真棒答案,雷米勒博的它如何在德尔福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.