如何检查一个字符串是否被Base64编码

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

我如何检查一个字符串是否被Base64编码?

362846 次浏览

你可以:

  • 检查长度是否为4个字符的倍数
  • 检查每个字符都在A-Z, A-Z, 0-9, +, /集合中,除了末尾的填充为0,1或2 '='字符

如果你期望它是base64,那么你可能只需要使用平台上可用的库试一试将其解码为字节数组,如果它不是有效的base64则抛出异常。当然,这取决于你的平台。

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

您可以使用以下正则表达式来检查字符串是否构成有效的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}==

有很多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?

如果你正在使用Java,你实际上可以使用commons-codec

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


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

(更新1)弃用通知 使用而不是< / p >

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);
}

检查如果字符串的长度是4的倍数。然后使用这个正则表达式来确保字符串中的所有的人物是base64字符。

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

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

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;
}
}

当你知道原始内容的长度(例如校验和)时,这个片段可能会很有用。它检查编码的表单是否具有正确的长度。

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() ;
}

如果RegEx不起作用,而您知道原始字符串的格式风格,则可以通过对该格式进行RegEx来反转逻辑。

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

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');
}

试试这个:

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");
}
}

这在Python中是有效的:

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

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

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


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

< >强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;
}

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

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");
}
/^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/

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

这在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编码的返回真正< em > < / em >,如果string here不是base64编码的返回< em >假< / em >

不可能检查一个字符串是否是base64编码的。只有当该字符串是base64编码的字符串格式时才有可能验证,这意味着它可能是由base64编码生成的字符串(为了验证这一点,可以根据regexp验证字符串,也可以使用库,这个问题的许多其他答案提供了很好的检查方法,所以我不会详细讨论)。

例如,字符串flow是一个有效的base64编码字符串。但是不可能知道它只是一个简单的字符串,一个英文单词flow,还是它是一个以64为基数编码的字符串~Z0

如果解码时得到一个ASCII字符的字符串,则字符串为 没有编码的< / p >

(RoR) ruby解决方案:

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


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

我试着用这个,是的,这个有用

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

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

string.lastIndexOf("=") >= 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

对颤振,我测试了上面的几个注释,并将其翻译成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,
);


final bool isBase64Valid = rx.hasMatch(value);


if (isBase64Valid == true) {return true;}
else {return false;}


}


else {return false;}


}
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();
}

在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();
}

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

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

在某些情况下,==也是可选的。

最好!