使用JavaScript确定字符串是否在base64中
我正在使用使用JavaScript确定字符串是否在base64中,javascript,base64,Javascript,Base64,我正在使用window.atob('string')函数将一个字符串从base64解码为一个字符串。现在我想知道,有没有办法检查“string”实际上是有效的base64?如果字符串不是base64,我希望得到通知,以便我可以执行不同的操作。如果“有效”表示“其中只有base64字符”,则检查/[a-Za-z0-9+/=]/ 如果“valid”表示“legal”base64编码字符串,则应检查末尾的= 如果“有效”表示解码后它是合理的,那么它需要领域知识。如果您想检查它是否可以解码,您只需尝试解
window.atob('string')
函数将一个字符串从base64解码为一个字符串。现在我想知道,有没有办法检查“string”实际上是有效的base64?如果字符串不是base64,我希望得到通知,以便我可以执行不同的操作。如果“有效”表示“其中只有base64字符”,则检查/[a-Za-z0-9+/=]/
如果“valid”表示“legal”base64编码字符串,则应检查末尾的=
如果“有效”表示解码后它是合理的,那么它需要领域知识。如果您想检查它是否可以解码,您只需尝试解码并查看它是否失败:
try {
window.atob(str);
} catch(e) {
// something failed
// if you want to be specific and only catch the error which means
// the base 64 was invalid, then check for 'e.code === 5'.
// (because 'DOMException.INVALID_CHARACTER_ERR === 5')
}
我会用正则表达式来表示。试试这个:
/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/
说明:
^ # Start of input
([0-9a-zA-Z+/]{4})* # Groups of 4 valid characters decode
# to 24 bits of data for each group
( # Either ending with:
([0-9a-zA-Z+/]{2}==) # two valid characters followed by ==
| # , or
([0-9a-zA-Z+/]{3}=) # three valid characters followed by =
)? # , or nothing
$ # End of input
此方法尝试解码,然后编码并与原始进行比较。还可以与其他针对出现解析错误的环境的答案结合使用。从正则表达式的角度来看,也可能有一个看起来像有效的base64但不是实际的base64的字符串
if(btoa(atob(str))==str){
//...
}
这应该能奏效
function isBase64(str) {
if (str ==='' || str.trim() ===''){ return false; }
try {
return btoa(atob(str)) == str;
} catch (err) {
return false;
}
}
在此基础上,使用正则表达式对base64有效性进行简单的真/假测试非常简单,如下所示:
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
base64regex.test("SomeStringObviouslyNotBase64Encoded..."); // FALSE
base64regex.test("U29tZVN0cmluZ09idmlvdXNseU5vdEJhc2U2NEVuY29kZWQ="); // TRUE
更新2021
- 根据下面的注释,这个基于正则表达式的解决方案提供了比简单的
`ingtry
更精确的检查,因为后者不检查atob
-填充。根据=
-填充只能在base16编码或数据长度已知时忽略=
- 基于Regex的解决方案似乎也是kai最快的解决方案。由于jsperf看起来很不稳定,我做了一个测试来证实这一点
const notBase64 = /[^A-Z0-9+\/=]/i;
export default function isBase64(str) {
assertString(str); // remove this line and make sure you pass in a string
const len = str.length;
if (!len || len % 4 !== 0 || notBase64.test(str)) {
return false;
}
const firstPaddingChar = str.indexOf('=');
return firstPaddingChar === -1 ||
firstPaddingChar === len - 1 ||
(firstPaddingChar === len - 2 && str[len - 1] === '=');
}
由于这里发布了两种可能性(regex和try-catch),我确实比较了这两种方法的性能: Regex解决方案似乎更快、更清晰。 不确定正则表达式是否能捕获所有案例,但对于我的测试来说,它工作得非常好 感谢@Philzen的正则表达式 p、 美国 如果有人对找到安全解码base64字符串的最快方法感兴趣(我就是这样来到这里的):
对于我来说,字符串很可能是编码的base64,如果:
A-Z
A-Z
0-9
+/=
=
(0-3个字符)函数isBase64(str)
{
返回str.length%4==0&&/^[A-Za-z0-9+/]+[=]{0,3}$/.test(str);
}
我知道已经很晚了,但我在这里尽量简化
function isBase64(encodedString) {
var regexBase64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
return regexBase64.test(encodedString); // return TRUE if its base64 string.
}
它还可以包含
+
和/
,最后可能包含=
。具体取决于实现。。通常第63和64个字符被选择为+和/,但可能会有所不同。通常以一个或两个=
字符结尾,以偶数字符所需的字符为准。@pimvdb&bdares:Oops,yep;注意:base64的一些实现不需要填充。检查“=”可能不够。=
填充并不总是存在。+1更好。(我找不到任何东西说明它是否必须在失败时抛出异常;一个指向该异常的参考链接会很方便:)@Dave Newton:建议将其添加到HTML5规范中:“如果输入字符串不是有效的base64数据,则抛出无效字符错误异常。”这将是一个很好的解决方案,但它似乎不会在解码失败时抛出异常(至少在Chrome中不会);请参见下面丹·史密斯的答案,了解完整的方法。我认为这是一个比所选方法更好的解决方案。请参见对我关于填充的答案的评论。@DaveNewton你是什么意思?那不总是存在吗?此函数不需要=
。关于填充,例如len%4!==0根据=
-填充只能在base16编码时忽略,或者如果数据长度是隐式已知的。奇怪的是,对于某些PNG图像,填充对我不起作用。数据不起作用。不知何故,许多其他字符串通过了此验证。这不起作用btoa(atob('test'))='test'返回true。问题是许多普通字符串都是valide base64,尽管它们不是base64编码的。在这种情况下,有效的base64普通字符串被解码为另一个非base64字符串,该字符串可以编码为原始普通字符串。是否有一些固有的base64结构我们可以测试,它只适用于bse64编码的字符串?为什么您认为test
不是有效的base64?如果str为null或未定义,str.trim()将终止js执行。。如果(!str)返回false,则输入;在第一行,你能解释一下为什么这个结果是正确的吗?base64Regex.test(1234)@modernator-因为'1234'是一个长度为4的字符串-因此匹配第一个([0-9a-zA-Z+/]{4})*regex的部分不适用于f.i.“思维导图”base64Regex.test(“思维导图”);//返回TRUE,同时返回FALSEexpected@cavo789仍然正确,因为“思维导图”是一个有效的base64字符串。。。您可以轻松验证自己:window.btoa(“\u009a)Ý\u0099ªl”)
是的,atob
对于测试字符串是否是base64编码的不是一个好选项,因为它太松散了。它允许base64编码的字符串不需要所需的=
或=
填充。Base64编码字符串的长度应该是4的倍数。我认为这是所有字符串中最好的答案。SomeStringObviouslyNotBase64Encoded
测试为FALSE,尽管它是有效的Base64:atob(“SomeStringObviouslyNotBase64Encoded”)
返回JJÚ–¾××Zîw(uç
。是否可以改进此正则表达式以使其100%准确?实际上,正是window.atob
接受不完全正确的字符串。您的示例正好有35个字符,并且