[英]Determine if string is in base64 using JavaScript
我正在使用window.atob('string')
function 将字符串从 base64 解码为字符串。 现在我想知道,有什么方法可以检查“字符串”是否真的有效 base64? 如果字符串不是 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')
}
基于@anders-marzi-tornblad 的答案,使用正则表达式对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
try
`ing atob
更准确的检查,因为后者不检查=
-padding。 根据RFC4648 =
-padding 只能在 base16 编码或隐含已知数据长度的情况下被忽略。这应该可以解决问题。
function isBase64(str) {
if (str ==='' || str.trim() ===''){ return false; }
try {
return btoa(atob(str)) == str;
} catch (err) {
return false;
}
}
如果“有效”意味着“其中只有 base64 字符”,则检查/[A-Za-z0-9+/=]/
。
如果“有效”表示“合法”base64 编码的字符串,那么您应该检查末尾的=
。
如果“有效”意味着解码后它是合理的,那么它需要领域知识。
我会为此使用正则表达式。 试试这个:
/^([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){
//...
}
这是在我最喜欢的验证库之一中完成的:
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] === '=');
}
https://github.com/chriso/validator.js/blob/master/src/lib/isBase64.js
由于这里发布的主要有两种可能性(regex vs try catch),我确实比较了两者的性能: https : //jsperf.com/base64-check/
正则表达式解决方案似乎更快更明显。 不确定正则表达式是否能捕获所有情况,但对于我的测试,它运行良好。
感谢@Philzen 的正则表达式!
ps
如果有人有兴趣找到安全解码 base64 字符串的最快方法(这就是我来到这里的方式): https : //jsperf.com/base64-decoding-check
对我来说,如果满足以下条件,字符串很可能是经过编码的 base64:
AZ
az
0-9
+/=
=
(0-2个字符)所以代码是
function isBase64(str)
{
return str.length % 4 == 0 && /^[A-Za-z0-9+/]+[=]{0,2}$/.test(str);
}
nodejs 中的实现(不仅验证允许的字符,还验证 base64 字符串)
const validateBase64 = function(encoded1) {
var decoded1 = Buffer.from(encoded1, 'base64').toString('utf8');
var encoded2 = Buffer.from(decoded1, 'binary').toString('base64');
return encoded1 == encoded2;
}
我尝试了以下答案,但存在一些问题。
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
base64regex.test(value)
当使用它时,“BBBBB”大写字母将是真实的。 “4444”也是如此。
我添加了一些代码来为我正常工作。
function (value) {
var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
if (base64regex.test(value) && isNaN(value) && !/^[a-zA-Z]+$/.test(value)) {
return decodeURIComponent(escape(window.atob(value)));
}
把我的结果扔在这里。 在我的例子中,有一个不是 base64 但有效的字符串 base64 所以它被解码成乱码。 (即根据通常的正则表达式,yyyyyyyy 有效 base64)
我的测试结果是首先检查字符串是否是有效的 base64 字符串,使用其他人在这里共享的正则表达式,然后解密它并测试它是否是有效的 ascii 字符串,因为(在我的情况下)我应该只取回 ascii 字符。 (这可能会扩展到包括可能不属于 ascii 范围的其他字符。)
这是多个答案的混合体。
let base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
function isBase64(str) {
if (str ==='' || str.trim() ===''){ return false; }
try {
if (base64regex.test(str)) {
return /^[\x00-\x7F]*$/.test(atob(str));
} else {
return false
}
} catch (err) {
// catch
}
}
与我的 JavaScript 答案一样,我不知道自己在做什么。 所以可能有更好的方法来写出来。 但它适用于我的需要,并涵盖了当您有一个不应为 base64 但有效且仍解密为 base64 的字符串时的情况。
我知道为时已晚,但我试图在这里让它变得简单;
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.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.