在 Delphi XE7 中使用 NetEncoding Base64 解码字符串?
Base64-decode a string using NetEncoding in Delphi XE7?
在 Delphi XE7 Update 1 中,尝试在 VCL 程序中执行此代码时:
uses System.NetEncoding;
...
tempstring := TNetEncoding.Base64.Decode(tempstring);
我收到此错误消息:
那么如何使用 NetEncoding 对字符串进行 base64 解码?
您正在调用接受 base64 编码文本和 returns 字符串的 Decode
重载。 Decode
方法的实现方式如下:
- 将 base64 解码为二进制。
- 将二进制文件视为 UTF-8 编码文本。
- 将 UTF-8 字节解码为文本。
您的错误消息表明第 1 步生成的二进制文件不是有效的 UTF-8。为了弄清楚为什么会这样,需要了解 base64 编码文本的来源。
您当前的代码假定发生了以下过程来创建 base64 编码值:
- 将一些文本编码为 UTF-8 字节。
- Base 64 编码这些字节。
问题不一定出在你的代码解码上。问题是您的解码与最初编码的过程不匹配。错误可能在于原始编码或解码。您需要检查 base64 值是如何编码的。是否使用上述步骤对其进行了编码?
如果非要我猜的话,我会怀疑原始数据实际上不是文本数据。我的猜测是原始数据是二进制的,即字节流。我怀疑您是从一些代码开始的,这些代码在 AnsiString
变量中保存了二进制数据。 Delphi 代码以这种方式滥用字符串是很常见的。由于历史原因,似乎已经将 AnsiString
用于保存二进制数据的传说写入了。我想这一切都是从 Delphi 2 引入 AnsiString
开始的,那时还没有动态数组。
无论如何,如果您以前一直使用 AnsiString
来保存二进制数据,那么您应该借此机会停止这样做。例如,为此目的使用 TBytes
。在这种情况下,您将使用:
var
bytes: TBytes;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
将您的 base64 值解码为二进制。
因此,假设您拥有的 base64 实际上是 ANSI 编码的文本。然后你会像这样解码它:
var
bytes: TBytes;
text: string;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
text := TEncoding.ANSI.GetString(bytes);
这假定您解码的机器上的主流 ANSI 代码页。如果您需要指定一个 ANSI 代码页,那么您可以这样写:
var
bytes: TBytes;
text: string;
Encoding: TEncoding;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
Encoding := TEncoding.GetEncoding(CodePage);
try
text := Encoding.GetString(bytes);
finally
Encoding.Free;
end;
如您所见,我现在只剩下猜测了。如果你想取得进步,你会发现你的数据是如何编码的。
在 Delphi XE7 Update 1 中,尝试在 VCL 程序中执行此代码时:
uses System.NetEncoding;
...
tempstring := TNetEncoding.Base64.Decode(tempstring);
我收到此错误消息:
那么如何使用 NetEncoding 对字符串进行 base64 解码?
您正在调用接受 base64 编码文本和 returns 字符串的 Decode
重载。 Decode
方法的实现方式如下:
- 将 base64 解码为二进制。
- 将二进制文件视为 UTF-8 编码文本。
- 将 UTF-8 字节解码为文本。
您的错误消息表明第 1 步生成的二进制文件不是有效的 UTF-8。为了弄清楚为什么会这样,需要了解 base64 编码文本的来源。
您当前的代码假定发生了以下过程来创建 base64 编码值:
- 将一些文本编码为 UTF-8 字节。
- Base 64 编码这些字节。
问题不一定出在你的代码解码上。问题是您的解码与最初编码的过程不匹配。错误可能在于原始编码或解码。您需要检查 base64 值是如何编码的。是否使用上述步骤对其进行了编码?
如果非要我猜的话,我会怀疑原始数据实际上不是文本数据。我的猜测是原始数据是二进制的,即字节流。我怀疑您是从一些代码开始的,这些代码在 AnsiString
变量中保存了二进制数据。 Delphi 代码以这种方式滥用字符串是很常见的。由于历史原因,似乎已经将 AnsiString
用于保存二进制数据的传说写入了。我想这一切都是从 Delphi 2 引入 AnsiString
开始的,那时还没有动态数组。
无论如何,如果您以前一直使用 AnsiString
来保存二进制数据,那么您应该借此机会停止这样做。例如,为此目的使用 TBytes
。在这种情况下,您将使用:
var
bytes: TBytes;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
将您的 base64 值解码为二进制。
因此,假设您拥有的 base64 实际上是 ANSI 编码的文本。然后你会像这样解码它:
var
bytes: TBytes;
text: string;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
text := TEncoding.ANSI.GetString(bytes);
这假定您解码的机器上的主流 ANSI 代码页。如果您需要指定一个 ANSI 代码页,那么您可以这样写:
var
bytes: TBytes;
text: string;
Encoding: TEncoding;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
Encoding := TEncoding.GetEncoding(CodePage);
try
text := Encoding.GetString(bytes);
finally
Encoding.Free;
end;
如您所见,我现在只剩下猜测了。如果你想取得进步,你会发现你的数据是如何编码的。