代码之家  ›  专栏  ›  技术社区  ›  LarryF

用于解析或验证Base64数据的正则表达式

  •  78
  • LarryF  · 技术社区  · 17 年前

    我有一个Base64解码器,它不能完全依赖输入数据来遵循RFC规范。因此,我面临的问题可能是Base64数据可能无法分解为78(我认为是78,我必须再次检查RFC,所以如果确切数字错误,请不要告诉我)字符行,或者这些行可能不会以CRLF结尾;因为它可能只有CR或LF,或者两者都没有。

    所以,我花了很长时间来解析Base64格式的数据。因此,下面的示例不可能可靠地解码。为了简洁起见,我将只显示部分MIME头。

    Content-Transfer-Encoding: base64
    
    VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
    

    好的,解析这是没有问题的,这正是我们所期望的结果。在99%的情况下,使用任何代码至少验证缓冲区中的每个字符是否为有效的base64字符都可以完美地工作。但是,下一个例子对这一组合产生了影响。

    Content-Transfer-Encoding: base64
    
    http://www.stackoverflow.com
    VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
    

    我的Base64解码器将第二个示例解码为以下数据流。请记住,原始流都是ASCII数据!

    [0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
    2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
    

    有谁能同时解决这两个问题?除了使用不同的规则对数据进行两次转换并比较结果之外,我甚至不确定这是否可行。但是,如果您采用这种方法,您相信哪种输出?似乎ASCII启发式是关于 解决方案,但这会增加多少代码、执行时间和复杂性,使病毒扫描程序变得如此复杂,而这段代码实际上涉及到病毒扫描程序?您将如何训练启发式引擎以了解哪些是可接受的,哪些是不可接受的?


    更新:

    关于这个问题继续得到的视图数量,我决定发布一个简单的正则表达式,我在C#应用程序中使用了3年,现在有几十万个事务。老实说,我喜欢你给出的答案 Gumbo 最好的,这就是为什么我选择它作为选择答案。但是对于任何使用C#的人来说,如果他们想寻找一种非常快速的方法来至少检测字符串或字节[]是否包含有效的Base64数据,我发现以下方法对我来说非常有效。

    [^-A-Za-z0-9+/=]|=[^=]|={3,}$
    

    Base64数据的格式不正确 RFC1341 非常 建议你阅读 RFC4648 秋葵

    4 回复  |  直到 4 年前
        1
  •  163
  •   Gumbo    17 年前

    RFC 4648 :

    在许多情况下,数据的基本编码用于存储或传输环境中的数据,这些环境可能出于遗留原因,仅限于US-ASCII数据。

    但是,如果您只是在寻找一个正则表达式来匹配Base64编码的单词,则可以使用以下方法:

    ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
    
        2
  •  38
  •   njzk2    15 年前
    ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
    

    此项与空字符串不匹配:

    ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$
    
        3
  •  5
  •   oylenshpeegul    17 年前

    : . “将显示在有效的Base64中,因此我认为您可以毫不含糊地丢弃 http://www.stackoverflow.com 线在Perl中,比如说

    my $sanitized_str = join q{}, grep {!/[^A-Za-z0-9+\/=]/} split /\n/, $str;
    
    say decode_base64($sanitized_str);
    

    这是StackOverflow exmaple的简单ASCII Base64。

        4
  •  4
  •   Bogdan Nechyporenko    11 年前

    到目前为止,我能找到的最好的正则表达式就在这里 https://www.npmjs.com/package/base64-regex

    它在当前版本中看起来像:

    module.exports = function (opts) {
      opts = opts || {};
      var regex = '(?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)';
    
      return opts.exact ? new RegExp('(?:^' + regex + '$)') :
                        new RegExp('(?:^|\\s)' + regex, 'g');
    };
    
        5
  •  4
  •   Community Mohan Dere    4 年前

    到目前为止给出的答案未能检查Base64字符串是否将所有pad位设置为0,因为它是Base64的规范表示形式(这在某些环境中很重要,请参阅) https://www.rfc-editor.org/rfc/rfc4648#section-3.5 别名 对于同一个二进制字符串是不同的编码。在某些应用程序中,这可能是一个安全问题。

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

    引用的RFC认为空字符串有效(请参阅 https://www.rfc-editor.org/rfc/rfc4648#section-10 )因此,上面的正则表达式也是如此。

    base64url的等效正则表达式(同样,请参考上述RFC)为:

    ^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-][AQgw]==|[A-Za-z0-9_-]{2}[AEIMQUYcgkosw048]=)?$
    
        6
  •  4
  •   Jayani Sumudini    5 年前

    base64图像 我们可以用这个正则表达式

    /^数据:图像/(?:gif | png | jpeg | bmp | webp)(?:;charset=utf-8)?;base64,(?:[A-Za-z0-9]|[+/])+={0,2}

      private validBase64Image(base64Image: string): boolean {
        const regex = /^data:image\/(?:gif|png|jpeg|bmp|webp|svg\+xml)(?:;charset=utf-8)?;base64,(?:[A-Za-z0-9]|[+/])+={0,2}/;
        return base64Image && regex.test(base64Image);
      }
    
        7
  •  3
  •   Paul    5 年前

    下面是另一个正则表达式:

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

    它满足以下条件:

    • 字符串长度必须是四的倍数- (?=^(.{4})*$)
    • [A-Za-z0-9+/]*
    • 它的结尾最多可以有两个填充(=)字符- ={0,2}
    • 它接受空字符串
        8
  •  1
  •   Paul M    4 年前

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

    事实上,这是混合的 this that

    推荐文章