BASE64编码和解码无法正常工作

时间:2014-02-25 21:39:56

标签: android delphi base64 delphi-xe5

我正在使用Delphi XE5中的android应用程序,我需要对某些字符串进行BASE64编码和解码。

此功能适用于英文字符,但我想编码€,$或任何特殊的iso8859-2字符编码不起作用。

知道如何修复它吗?

我找到了BASE64单元http://www.delphipraxis.net/991-base64-mime-en-decoding.html

但FireMonkey是否支持AnsiString和PAnsiChar类型以及要包含哪些单位才能使用此类型?

我的代码

uses IdCoderMIME;
...

function Encode64(S: string): string;
var
  IdEncoderMIME: TIdEncoderMIME;
begin
  try
    IdEncoderMIME := TIdEncoderMIME.Create(nil);
    Result := IdEncoderMIME.EncodeString(S);
  finally
    IdEncoderMIME.Free;
  end;
end;

function Decode64(S: string): string;
var
  IdDecoderMIME: TIdDecoderMIME;
var
  IdDecoderMIME: TIdDecoderMIME;
begin
  try
    IdDecoderMIME := TIdDecoderMIME.Create(nil);
    Result := IdDecoderMIME.DecodeString(S);
  finally
    IdDecoderMIME.Free;
  end;
end;

2 个答案:

答案 0 :(得分:6)

正式,Delphi 不会支持移动平台上的AnsiString(P)AnsiChar非正式,它们的支持代码仍然存在于编译器和RTL中,它只是隐藏,因此您无法再访问它。可以使用third-party patch重新启用访问权限。

编码/解码字符串时,必须考虑字符编码。 Base64编码字节,而不是字符。在将Base64编码为字节之前,必须将字符串转换为字节序列,然后Base64对字节序列进行解码,然后再将其转换回字符串。

对于该字符串< - >字节转换,TIdEncoderMIME.EncodeString()TIdDecoderMIME.DecodeString()方法具有可选的TIdTextEncodingIIdTextEncoding参数(取决于您的Indy版本)。如果您没有指定文本编码,Indy将使用其默认文本编码,默认情况下为7位ASCII(可通过IdGlobal.GIdDefaultTextEncoding变量进行配置)。

例如:

uses
  ..., IdGlobal, IdCoderMIME;

function Encode64(const S: string: const ByteEncoding: IIdTextEncoding = nil): string;
begin
  Result := TIdEncoderMIME.EncodeString(S, ByteEncoding);
end;

function Decode64(const S: string: const ByteEncoding: IIdTextEncoding = nil): string;
begin
  Result := TIdDecoderMIME.DecodeString(S, ByteEncoding);
end;

uses
  ..., IdGlobal;

var
  s, base64: string;
begin
  s := '€$';
  base64 := Encode64(s, IndyTextEncoding_UTF8);
  s := Decode64(base64, IndyTextEncoding_UTF8);
end;

uses
  ..., IdGlobal;

var
  s, base64: string;
  enc: IIdTextEncoding;
begin
  enc := IndyTextEncoding(28592); // ISO-8859-2
  s := '€$';
  base64 := Encode64(s, enc);
  s := Decode64(base64, enc);
end;

uses
  ..., IdGlobal, IdGlobalProtocols;

var
  s, base64: string;
  enc: IIdTextEncoding;
begin
  enc := CharsetToEncoding('ISO-8859-2');
  s := '€$';
  base64 := Encode64(s, enc);
  s := Decode64(base64, enc);

答案 1 :(得分:5)

关键是base64是字节数组到文本的编码。因此,如果您希望对文本进行编码,则必须先将文本转换为字节数组。为此,您需要选择特定的文本编码。

为了举例,我们假设你的文本编码是UTF-8。将文本编码为base64的过程如下所示:

  1. 使用UTF-8编码将纯文本编码为字节数组。
  2. 将该字节数组编码为base64字符串。
  3. 反方向如下:

    1. 将base64字符串解码为字节数组。
    2. 使用UTF-8编码将字节数组解码为字符串。
    3. Delphi附带了可以执行所有这些步骤的库。 TEncoding类处理UTF-8部分,Soap.EncdDecd部分处理base64。这里不需要使用Indy来执行base64编码。

      不幸的是,EncodeStringDecodeString功能位于Soap.EncdDecd do not handle Unicode correctly。我更愿意避免使用EncodeStreamDecodeStream函数来完成所有操作。像这样:

      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;