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

xJe*_*nej 2 delphi base64 android 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;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 6

正式地说,德尔福支持AnsiString并且(P)AnsiChar在移动平台上. 非正式地,它们的支持代码仍然存在于编译器和RTL中,它只是隐藏,因此您无法再访问它.有一个第三方补丁可以重新启用访问.

编码/解码字符串时,必须考虑字符编码.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;
Run Code Online (Sandbox Code Playgroud)

uses
  ..., IdGlobal;

var
  s, base64: string;
begin
  s := '€$';
  base64 := Encode64(s, IndyTextEncoding_UTF8);
  s := Decode64(base64, IndyTextEncoding_UTF8);
end;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

uses
  ..., IdGlobal, IdGlobalProtocols;

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


Dav*_*nan 6

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

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

  1. 使用UTF-8编码将纯文本编码为字节数组.
  2. 将该字节数组编码为base64字符串.

在相反的方向,它是这样的:

  1. 将base64字符串解码为字节数组.
  2. 使用UTF-8编码将字节数组解码为字符串.

Delphi附带了可以执行所有这些步骤的库.的TEncoding类处理UTF-8的一部分,并且所述Soap.EncdDecd单元确实BASE64.这里不需要使用Indy来执行base64编码.

不幸的是EncodeString,DecodeString函数Soap.EncdDecd 并没有正确处理Unicode.我更喜欢避免它们并使用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;
Run Code Online (Sandbox Code Playgroud)