RegExparsing或validationBase64数据

是否有可能使用RegEx来validation或清理Base64数据? 这是一个简单的问题,但推动这个问题的因素是困难。

我有一个Base64分析器,不能完全依赖input数据来遵循RFC规范。 所以,我面对的问题是可能不会分解为78(我认为是78,我不得不仔细检查RFC,所以如果确切的数字是错误的,我不认为)字符行,或者线路不能在CRLF中结束,因为它可能只有CR或LF,或者没有。

所以,我已经有一段时间来parsingBase64格式的数据,所以像下面这样的例子变得不可能正确解码。 为了简洁,我只会显示部分MIME头文件…

Content-Transfer-Encoding: base64 VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu 

好吧,parsing这个没有问题,这正是我们所期望的结果。 在99%的情况下,使用任何代码至lessvalidation在缓冲区中的每个字符是一个有效的base64字符,完美的作品。 但是,这引发了一场混战。

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

这是我在某些病毒和其他东西中看到的利用某些邮件阅读器阅读的b64编码的一个版本,它希望不惜一切代价来parsingmime,而不是严格按照本书进行parsing,而不是RFC; 如果你愿意。

我的base64解码器解码第二个例子到下面的数据stream。 原始stream是全部ASCII数据!

 0x86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D 2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8 

任何人都有一个很好的方法来同时解决这两个问题? 我不确定甚至有可能,除了对数据进行两次不同规则的转换,并对结果进行比较,甚至是这样,你信任哪一个呢? 看起来,ASCII Heuristics就是最好的解决scheme,但是代码和执行时间又多了多less,就像病毒扫描程序一样复杂,这个代码涉及到了什么? 你将如何训练启发式引擎来学习什么是可接受的b64,哪些不是?


更新:

做这个问题继续得到的意见的数量,我已经决定张贴我已经在C#应用程序中使用了3年的简单RegEx现在,成千上万的交易。 老实说,我喜欢Gumbo最好的答案,这就是为什么我select它作为select的答案。 但是,对于任何使用C#的人来说,至less要查找一个非常快捷的方法来检测string或byte []是否包含有效的b64数据,正如我所说的,这对我来说工作得非常好。

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

是的,这是针对base64数据的STRING ,而不是格式正确的RFC1341消息。 因此,如果您正在处理此类数据,请在尝试使用上述RegEx之前考虑这一点。 如果你正在处理Base16,Base32,Radix甚至Base64用于其他目的(URL,文件名,XML编码等),那么强烈build议你阅读Gumbo在他的回答中提到的RFC4648 ,因为你需要做好在尝试使用此问题/答案集中的build议之前,了解实现所使用的字符集和终止符。

从RFC 4648 :

在许多情况下,数据的基本编码被用于在可能由于传统原因被限制为US-ASCII数据的环境中存储或传送数据。

因此,如果数据被认为是危险的,则取决于使用编码数据的目的。

但是,如果您只是寻找一个正则expression式来匹配Base64编码的单词,您可以使用以下内容:

 ^(?:[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}=)?$ 

这一个很好,但会匹配一个空的String

这一个不匹配空string:

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

”和“ ”都不会在有效的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示例的简单ASCII Base64。

我能find的最好的正则expression式在这里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'); }; 
Interesting Posts