1

我知道已经有很多关于这方面的问题,形式各异。我的问题稍微直接一些。

使用 Free Pascal 和 s:=DecodeStringBase64(s); 函数,是否无论如何要验证作为 s 传递的解码字符串是否实际上是从正确的 Base64 输入数据中解码的,以避免解码垃圾?

我所做的最好的事情是使用 reg exp 来识别潜在的 Base64 数据(来自此处接受的答案)。然后我使用 mod 检查它是否可以被 4 整除。如果它可以被 4 整除,我将它传递给 DecodeStringBase64。但是,尽管匹配 reg exp,我仍然收到很多误报和返回的数据,这些数据已经“解码”但显然不是 Base64。例如,“WindowsXP=" 匹配表达式但不是 Base64 编码数据。

同样,名称“Ted”编码为 VGVk,它甚至没有通常的“=”填充(有助于将其标记为页脚),但它仍然是我想查找和解码的潜在 Base64 片段。

在 PHP 中,有base64_decode()可以传递一个 true 参数来帮助验证。

AFAIK,Free Pascal 在DecodeStringBase64中没有这个,我需要一些验证方法。

其他关于解码和编码主题的有用回复,如果读者碰巧像我昨天一样在寻找它,在这里

4

2 回答 2

2

简短的回答是否定的,Base64 编码字符串没有 100% 的有效验证。

编码字符串中的=符号Base64并不重要,它是 for padding,因此它并不总是需要存在(编码字符串的长度必须是 4 的倍数)。您只能检查字符串长度是否为 4 的倍数,检查 Base64 字母表中的有效字符(请参阅 参考资料)并验证输入字符串末尾Page 5, Table 1是否有不超过两个填充符号字符。=这是一个可以验证传递的字符串是否可以是有效的 Base64 编码字符串的代码(无论如何,您无能为力):

function CanBeValidBase64EncodedString(const AValue: string): Boolean;
const
  Base64Alphabet = ['A'..'Z', 'a'..'z', '0'..'9', '+', '/'];
var
  I: Integer;
  ValLen: Integer;
begin
  ValLen := Length(AValue);
  Result := (ValLen > 0) and (ValLen mod 4 = 0);
  if Result then
  begin
    while (AValue[ValLen] = '=') and (ValLen > Length(AValue) - 2) do
      Dec(ValLen);
    for I := ValLen downto 1 do
      if not (AValue[I] in Base64Alphabet) then
      begin
        Result := False;
        Break;
      end;
  end;
end;
于 2012-10-18T07:49:25.340 回答
1

在下一个版本 (2.6.2) 中,DecodeStringBase64 将有一个额外的布尔参数来调用严格模式。(在“流”版本中已经可用)。

如果存在验证错误,则会引发异常。

于 2012-10-18T08:02:29.070 回答