如何检查字符串是否是Base64编码的

问题描述 投票:0回答:25

我想解码 Base64 编码的字符串,然后将其存储在我的数据库中。如果输入不是 Base64 编码,我需要抛出一个错误。

如何检查字符串是否经过 Base64 编码?

base64
25个回答
339
投票

您可以使用以下正则表达式来检查字符串是否构成有效的base64编码:

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

在base64编码中,字符集是

[A-Z, a-z, 0-9, and + /]
。如果剩余长度小于 4,则用
'='
个字符填充字符串。

^([A-Za-z0-9+/]{4})*
表示字符串以 0 个或多个 Base64 组开头。

([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$
表示字符串以三种形式之一结尾:
[A-Za-z0-9+/]{4}
[A-Za-z0-9+/]{3}=
[A-Za-z0-9+/]{2}==


72
投票

如果您使用Java,您实际上可以使用commons-codec

import org.apache.commons.codec.binary.Base64;

String stringToBeChecked = "...";
boolean isBase64 = Base64.isArrayByteBase64(stringToBeChecked.getBytes());

[更新 1] 弃用通知 代替使用

Base64.isBase64(值);

   /**
     * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
     * method treats whitespace as valid.
     *
     * @param arrayOctet
     *            byte array to test
     * @return {@code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
     *         {@code false}, otherwise
     * @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0.
     */
    @Deprecated
    public static boolean isArrayByteBase64(final byte[] arrayOctet) {
        return isBase64(arrayOctet);
    }

58
投票

你可以:

  • 检查长度是否是4个字符的倍数
  • 检查每个字符是否都在 A-Z、a-z、0-9、+、/ 集合中,末尾的填充除外,即 0、1 或 2 个“=”字符

如果您期望它will是base64,那么您可能可以使用平台上可用的任何库来try将其解码为字节数组,如果它不是有效的base 64,则抛出异常。当然,取决于您的平台。


37
投票

从 Java 8 开始,您可以简单地使用 java.util.Base64 来尝试解码字符串:

String someString = "...";
Base64.Decoder decoder = Base64.getDecoder();

try {
    decoder.decode(someString);
} catch(IllegalArgumentException iae) {
    // That string wasn't valid.
}

15
投票

对于 PHP5 尝试这样

//where $json is some data that can be base64 encoded
$json=some_data;

//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{          
   echo "base64 encoded";          
}
else 
{
   echo "not base64 encoded"; 
}

将其用于 PHP7

 //$string parameter can be base64 encoded or not

function is_base64_encoded($string){
 //this will check if $string is base64 encoded and return true, if it is.
 if (base64_decode($string, true) !== false){          
   return true;        
 }else{
   return false;
 }
}

9
投票
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string

if (isBase64Valid) {
    // true if base64 formate
    console.log('It is base64');
} else {
    // false if not in base64 formate
    console.log('it is not in base64');
}

7
投票

试试这个:

public void checkForEncode(String string) {
    String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
    Pattern r = Pattern.compile(pattern);
    Matcher m = r.matcher(string);
    if (m.find()) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }
}

7
投票

无法检查字符串是否经过 Base64 编码。只能验证该字符串是否是 Base64 编码的字符串格式,这意味着它可能是由 Base64 编码生成的字符串(为了检查这一点,可以根据正则表达式验证字符串,或者可以使用库,许多这个问题的其他答案提供了很好的方法来检查这一点,所以我不会详细介绍)。

例如,字符串

flow
是有效的base64编码字符串。但无法知道它只是一个简单的字符串,一个英文单词
flow
,还是base 64编码的字符串
~Z0


5
投票

Base64 有许多变体,因此请考虑确定您的字符串类似于您期望处理的变体。因此,您可能需要根据索引和填充字符调整下面的正则表达式(即

+
/
=
)。

class String
  def resembles_base64?
    self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
  end
end

用途:

raise 'the string does not resemble Base64' unless my_string.resembles_base64?

5
投票

检查IF字符串的长度是4的倍数。然后使用此正则表达式来确保字符串中的所有字符都是base64字符。

\A[a-zA-Z\d\/+]+={,2}\z

如果您使用的库添加换行符作为遵守每行最多 76 个字符的规则,请将其替换为空字符串。


2
投票
/^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/

这个正则表达式帮助我识别了rails应用程序中的base64,我只有一个问题,那就是它识别字符串“errorDescription”,我生成一个错误,解决它只需验证字符串的长度。


2
投票

在 Java 中,下面的代码对我有用:

public static boolean isBase64Encoded(String s) {
        String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(s);
        return m.find();
    }

2
投票

对于 Flutter,我测试了上述几个注释并将其翻译成 Dart 函数,如下所示:

static bool isBase64(dynamic value) {
    if (value.runtimeType == String) {
        final RegExp rx = RegExp(r'^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$',
            multiLine: true,
            unicode: true,
        );
        return rx.hasMatch(value);
    }
    return false;
}

1
投票

这适用于 Python:

import base64

def IsBase64(str):
    try:
        base64.b64decode(str)
        return True
    except Exception as e:
        return False

if IsBase64("ABC"):
    print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
    print("ABC is NOT Base64-encoded.")

if IsBase64("QUJD"):
    print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
    print("QUJD is NOT Base64-encoded.")

总结:

IsBase64("string here")
如果 string here 是 Base64 编码,则返回 true
;如果 string here 不是 Base64 编码,则返回 false


1
投票

C# 这表现很棒:

static readonly Regex _base64RegexPattern = new Regex(BASE64_REGEX_STRING, RegexOptions.Compiled);

private const String BASE64_REGEX_STRING = @"^[a-zA-Z0-9\+/]*={0,3}$";

private static bool IsBase64(this String base64String)
{
    var rs = (!string.IsNullOrEmpty(base64String) && !string.IsNullOrWhiteSpace(base64String) && base64String.Length != 0 && base64String.Length % 4 == 0 && !base64String.Contains(" ") && !base64String.Contains("\t") && !base64String.Contains("\r") && !base64String.Contains("\n")) && (base64String.Length % 4 == 0 && _base64RegexPattern.Match(base64String, 0).Success);
    return rs;
}

0
投票

没有办法区分字符串和base64编码,除非您系统中的字符串有一些特定的限制或标识。


0
投票

当您知道原始内容的长度(例如校验和)时,此片段可能很有用。它检查编码形式的长度是否正确。

public static boolean isValidBase64( final int initialLength, final String string ) {
  final int padding ;
  final String regexEnd ;
  switch( ( initialLength ) % 3 ) {
    case 1 :
      padding = 2 ;
      regexEnd = "==" ;
      break ;
    case 2 :
      padding = 1 ;
      regexEnd = "=" ;
      break ;
    default :
      padding = 0 ;
      regexEnd = "" ;
  }
  final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
  final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
  return Pattern.compile( regex ).matcher( string ).matches() ;
}

0
投票

如果正则表达式不起作用,并且您知道原始字符串的格式样式,则可以通过对该格式进行正则表达式来反转逻辑。

例如,我使用 base64 编码的 xml 文件,并仅检查该文件是否包含有效的 xml 标记。如果不是,我可以假设它是 base64 解码的。这不是很动态,但对于我的小型应用程序来说效果很好。


0
投票

使用前面提到的正则表达式尝试一下:

String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
    System.out.println("it's a Base64");
}

...我们还可以做一个简单的验证,比如,如果有空格则不能是 Base64:

String myString = "Hello World";
 if(myString.contains(" ")){
   System.out.println("Not B64");
 }else{
    System.out.println("Could be B64 encoded, since it has no spaces");
 }

0
投票

如果解码时我们得到一个带有 ASCII 字符的字符串,那么该字符串就是 未编码

(RoR)红宝石溶液:

def encoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end

def decoded?(str)
  Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end

0
投票
Function Check_If_Base64(ByVal msgFile As String) As Boolean
Dim I As Long
Dim Buffer As String
Dim Car As String

Check_If_Base64 = True

Buffer = Leggi_File(msgFile)
Buffer = Replace(Buffer, vbCrLf, "")
For I = 1 To Len(Buffer)
    Car = Mid(Buffer, I, 1)
    If (Car < "A" Or Car > "Z") _
    And (Car < "a" Or Car > "z") _
    And (Car < "0" Or Car > "9") _
    And (Car <> "+" And Car <> "/" And Car <> "=") Then
        Check_If_Base64 = False
        Exit For
    End If
Next I
End Function
Function Leggi_File(PathAndFileName As String) As String
Dim FF As Integer
FF = FreeFile()
Open PathAndFileName For Binary As #FF
Leggi_File = Input(LOF(FF), #FF)
Close #FF
End Function

0
投票
import java.util.Base64;

    public static String encodeBase64(String s) {
        return Base64.getEncoder().encodeToString(s.getBytes());
    }

    public static String decodeBase64(String s) {
        try {
            if (isBase64(s)) {
                return new String(Base64.getDecoder().decode(s));
            } else {
                return s;
            }
        } catch (Exception e) {
            return s;
        }
    }

    public static boolean isBase64(String s) {
        String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(s);

        return m.find();
    }

0
投票

对于 Java 风格,我实际上使用以下正则表达式:

"([A-Za-z0-9+]{4})*([A-Za-z0-9+]{3}=|[A-Za-z0-9+]{2}(==){0,2})?"

在某些情况下,这也有

==
作为可选。

最好的!


0
投票

这适用于 Python:

def is_base64(string):
    return len(string) % 4 == 0 and re.test('^[A-Za-z0-9+\/=]+\Z', string)

-3
投票

我尝试使用这个,是的,它正在工作

^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$

但是我添加了至少检查字符结尾的条件是=

string.lastIndexOf("=") >= 0
© www.soinside.com 2019 - 2024. All rights reserved.