【问题标题】:BASE64 Encode and Decode is not workingBASE64 编码和解码不起作用
【发布时间】:2014-02-25 21:39:55
【问题描述】:

我正在 Delphi XE5 中开发 android applicatin,我需要对一些字符串进行 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;

【问题讨论】:

  • BASE64 是一组字节的字符串表示形式。要从字符串中获取字节,您还必须查看字符串的编码(ASCII、ANSI、UTF8、...)以及目标支持/期望的编码。 TEncoding.GetBytes。顺便说一句,这与 FireMonkey相关
  • 您在应用中使用 Indy 吗?

标签: android delphi base64 delphi-xe5


【解决方案1】:

官方,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);

【讨论】:

    【解决方案2】:

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

    为了举例,让我们假设您的文本编码是 UTF-8。将文本编码为 base64 的过程如下运行:

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

    相反的方向是这样的:

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

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多