Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript确定字符串是否在base64中_Javascript_Base64 - Fatal编程技术网

使用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
  • 根据下面的注释,这个基于正则表达式的解决方案提供了比简单的
    try
    `ing
    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,如果:

  • 它的长度可以被4整除
  • 使用
    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个字符,并且