如何检查字符串是否为base64编码

log*_*han 174 base64

我想解码base64编码的字符串,然后将其存储在我的数据库中.如果输入不是base64编码,我需要抛出一个错误.如何检查字符串是否为base64编码?

xua*_*uan 226

您可以使用以下正则表达式来检查字符串是否为base64编码:

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

在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}==.

  • 这只告诉输入**可能是**b64编码值,但它不能告诉输入**是否**实际上是b64编码值.换句话说,`abcd`将匹配,但它不一定代表`i·`的编码值,而只是一个简单的`abcd`输入 (56认同)
  • 只是想验证所以请帮助我的问题:这个正则表达式总是只引用base64字符串的保证是什么?如果有任何字符串没有空格且是4个字符的倍数,那么该字符串是否会被视为base64字符串???? (9认同)
  • @Adomas,“ pass”是完全有效的base64字符串,它解码为字节序列“ 0xa5”,“ 0xab”和“ 0x2c”。如果您没有更多的上下文来决定,为什么要优先丢弃它? (4认同)
  • 然后它是一个有效的base64字符串,可以解码.您可以添加最小长度约束; 例如,代替零或更多的四个组的重复,需要(例如)四个或更多.这也取决于你的问题; 如果您的用户经常使用长单词和纯ASCII(夏威夷语?)输入单个单词,那么与非base64输入通常包含空格,标点符号等相比,它更容易出错. (3认同)
  • 你的regexp是不正确的,因为它与空字符串不匹配,是根据RFC 4648的零长度二进制数据的base64编码. (3认同)
  • @LuisColorado,但这里的问题是“如何检查字符串是否为 base64 编码”,答案指出所提供的正则表达式验证字符串是否为 base64 编码 - 但事实并非如此,前提是正则表达式仅验证字符串是否为 base64编码字符串格式,但无法知道这是原始字符串,只是采用 base64 格式,还是编码字符串。 (2认同)
  • 这是一个很老的问题,但讨论似乎仍然是关于生命支持的!几个快速评论:正则表达式没有考虑在“有效”base64 字符串中经常出现的空白字符,尤其是那些属于 PEM 编码文件的一部分。此外,问题中还给出了一些上下文:假设解码值将仅包含可打印的 ASCII 字符。可以测试字符串以确定它是否可能是 base64 编码的,如果是,则进行解码,然后测试生成的字节数组以查看它是否仅包含可打印的 ASCII 字符。 (2认同)

zih*_*oyu 47

如果您使用的是Java,那么您实际上可以使用commons-codec

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

String stringToBeChecked = "...";
boolean isBase64 = Base64.isArrayByteBase64(stringToBeChecked.getBytes());
Run Code Online (Sandbox Code Playgroud)

  • 来自文档:`isArrayByteBase64(byte [] arrayOctet)`已弃用.1.5使用`isBase64(byte [])`,将在2.0中删除. (15认同)
  • 您也可以使用Base64.isBase64(String base64)而不是自己将其转换为字节数组. (7认同)
  • 可悲的是,基于文档:http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64.html#isBase64%28java.lang.String%29:"测试一个给定的String,看它是否只包含Base64字母表中的有效字符.目前该方法将空格视为有效." 这意味着这种方法有一些误报,如"空格"或数字("0","1"). (5认同)
  • 这个答案是错误的,因为给定“ stringToBeChecked =” some plain text“”之后,即使它不是Base64编码的值,它也会设置“ boolean isBase64 = true”。阅读commons-codec-1.4 Base64.isArrayByteBase64()的源代码,它仅检查字符串中的每个字符对于Base64编码而言是否有效,并留有空白。 (2认同)

Jon*_*eet 44

那么你可以:

  • 检查长度是4个字符的倍数
  • 检查每个字符是否在AZ,az,0-9,+,/集合中,除了最后的填充为0,1或2'='字符

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

  • @VictorYarema:我建议使用仅验证方法(要点)和解析方法(在要点之后)。 (2认同)

Sun*_*mar 13

尝试这样的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"; 
}
Run Code Online (Sandbox Code Playgroud)

  • 这是哪种语言?问题是在没有提及语言的情况下提出的 (2认同)
  • 如何?如果输入包含外部字符,则它不是 base64,对吗? (2认同)

Phi*_*ppe 11

从Java 8开始,您只需使用java.util.Base64来尝试解码字符串:

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

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

  • 现在已经不是这样了。异常处理表现相当不错。您最好不要忘记 Java Regex 非常慢。我的意思是:真的很慢!解码 Base64 并检查它是否(不)工作而不是将字符串与上述正则表达式匹配实际上更快。我做了一个粗略的测试,Java 正则表达式匹配比在解码时捕获最终异常慢大约六倍(!!)。 (7认同)
  • 使用此方法与字符串“Commit”将返回一个有效值,该值只是乱码。所以这似乎并不是万无一失的。 (3认同)
  • @seunggabi 为什么它会抛出字符串“dev”? (3认同)
  • 是的,这是一个选择,但是请不要忘记在Java中catch是相当昂贵的操作 (2认同)
  • 使用Java 11(而不是Java 8),Regex检查的速度甚至慢了22倍。(因为Base64解码变得更快。) (2认同)

小智 6

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');
}
Run Code Online (Sandbox Code Playgroud)


小智 6

尝试这个:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)


use*_*833 5

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

class String
  def resembles_base64?
    self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
  end
end
Run Code Online (Sandbox Code Playgroud)

用法:

raise 'the string does not resemble Base64' unless my_string.resembles_base64?
Run Code Online (Sandbox Code Playgroud)


Yaw*_*kye 5

请检查IF字符串的长度是4 Aftwerwards使用这个表达式来确保多的所有字符的字符串中的数据为base64字符。

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

如果您使用的库添加了一个换行符,以观察每行最多76个字符,请用空字符串替换它们。


Ado*_*mas 5

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

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