如何检测一个字符串是否为Base64编码?

6
哪种方法是检测字符串是否为Base64编码的最佳方法(使用Delphi)?
4个回答

5

您最好尝试解码它。如果解码失败,则输入未经base64编码。如果字符串成功解码,则输入可能已经进行了base64编码。


3
这将取决于用于解码的组件或函数的实现方式,例如如果您使用Indy的TIdDecoderMIME组件来解码一个无效的Base64字符串,则该组件不会引发任何异常或错误。 - RRUZ
3
@RRUZ提出了一个好观点。然而,需要传达的最重要的一点是,仅仅因为一个字符串可以被解码,并不意味着它最初是被编码的。 - David Heffernan

5
您可以检查字符串是否仅包含Base64有效字符
function StringIsBase64(const InputString : String ) : Boolean;
const
  Base64Chars: Set of AnsiChar = ['A'..'Z','a'..'z','0'..'9','+','/','='];
var
  i : integer;
begin
  Result:=True;
   for i:=1 to Length(InputString) do
   {$IFDEF UNICODE}
   if not CharInSet(InputString[i],Base64Chars) then
   {$ELSE}
   if not (InputString[i] in Base64Chars) then
   {$ENDIF}
   begin
     Result:=False;
     break;
   end;
end;
=字符用于填充,因此您可以为填充的base64字符串添加额外的验证功能,检查字符串的长度是否是4的倍数。

2
+1,不过证明反过来可能是更好的概念——即如果字符串包含有效范围之外的字符,则它不是Base64,否则它可能是或可能不是,正如其他答案中所讨论的那样。 - HMcG

4
除了RRUZ的回答,您还可以检查字符串的长度(它是否是4的倍数)。
function IsValidBase64(const aValue: string): Boolean;
var
  i: Integer;
  lValidChars: set of Char;
begin
  Result := aValue <> '';
  lValidChars := ['a'..'z', 'A'..'Z', '0'..'9', '/', '+'];
  //length of string should be multiple of 4
  if Length(aValue) mod 4 > 0 then
    Result := False
  else
    for i := 1 to Length(aValue) do
    begin
      if aValue[i] = '=' then
      begin
        if i < Length(aValue) - 1 then
        begin              
          Result := False;
          Exit;
        end
        else
          lValidChars := ['='];
      end
      else if not (aValue[i] in lValidChars) then
      begin
        Result := False;
        Break;
      end;
    end;
end;

请注意,此代码为Delphi 7代码,未进行Unicode调整。

2
@Lars 这个函数最好改名为 MightBeBase64 - David Heffernan
@Lars Truijens:是的,你说得对。如果你真的想做到这一点,你应该检查=是否只存在于末尾,并且只有一个或两个。 - The_Fox
@The_Fox 检查正确的终止符“=”并没有改变什么。许多随机字符串都可以通过此测试,但解码后却是无意义的。 - David Heffernan
@The_Fox,不是很好。由于将char分配给lValidChars,这无法编译,但无论如何,您仍然认为空字符串有效;-) - TLama
1
@TLama:有时候你在笔记本电脑上快速编辑时,孩子们四处奔跑,这种情况有时会发生 :) - The_Fox
显示剩余3条评论

4
正如已经在这里提到的,没有可靠的方法来验证某个字符串是否是Base64编码的,因此即使您将输入视为有效的Base64编码字符串,也不意味着该字符串实际上是以这种方式编码的。我在这里发布另一个验证函数的版本,根据RFC 4648进行验证:
  • 如果输入字符串不为空且其长度是4的倍数
  • 如果输入字符串最多包含两个填充字符,并且仅在字符串末尾
  • 如果输入字符串仅包含Base64字母表中的字符(请参见第5页,表格1

function IsValidBase64EncodedString(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;

1
PS:我在这里使用了“downto”迭代,因为怀疑字符串末尾可能有第三个“=”符号。 - TLama
1
我认为IsValidBase64EncodedString是比CanBe...更好的名称,因为它确实表明输入字符串是一个有效的base64编码字符串。 - kobik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接