是否可以使用正则表达式来验证或清理 Base64 数据?这是一个简单的问题,但驱动这个问题的因素是使它变得困难的因素。
我有一个不能完全依赖输入数据来遵循 RFC 规范的 Base64 解码器。因此,我面临的问题可能是 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
这是我在一些病毒和其他试图利用某些邮件阅读器希望不惜一切代价解析 mime 的东西中看到的 Base64 编码版本,而不是那些严格按照书本,或者更确切地说是 RFC 的东西;如果你愿意的话。
我的 Base64 解码器将第二个示例解码为以下数据流。请记住,原始流都是 ASCII 数据!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
任何人有一个很好的方法来一次解决这两个问题?我不确定这是否可能,除了对应用了不同规则的数据进行两次转换并比较结果之外。但是,如果您采用这种方法,您信任哪个输出?似乎 ASCII 启发式方法是最好的解决方案,但是对于像病毒扫描程序这样复杂的东西,这段代码实际上参与其中,会增加多少代码、执行时间和复杂性?您将如何训练启发式引擎以了解什么是可接受的 Base64,什么不是?
更新:
对于这个问题继续获得的视图数量,我决定发布我在 C# 应用程序中使用了 3 年的简单正则表达式,其中包含数十万个事务。老实说,我最喜欢Gumbo给出的答案,这就是我选择它作为选定答案的原因。但是对于任何使用 C# 并且正在寻找一种非常快速的方法来至少检测字符串或字节 [] 是否包含有效的 Base64 数据的人,我发现以下内容对我来说非常有效。
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
是的,这只是针对 Base64 数据的字符串,而不是格式正确的RFC1341消息。因此,如果您正在处理这种类型的数据,请在尝试使用上述 RegEx 之前考虑到这一点。如果您出于其他目的(URL、文件名、XML 编码等)处理 Base16、Base32、Radix 甚至 Base64,那么强烈建议您阅读Gumbo在他的回答中提到的RFC4648,因为您需要做好在尝试使用此问题/答案集中的建议之前,请了解实现使用的字符集和终止符。