【发布时间】:2010-10-03 06:28:05
【问题描述】:
是否可以使用正则表达式来验证或清理 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
这是我在一些病毒和其他东西中看到的 Base64 编码版本,它们试图利用一些邮件阅读者不惜一切代价想要解析 mime,而不是严格按照书本或 RFC 进行解析;如果你愿意的话。
我的 Base64 解码器将第二个示例解码为以下数据流。请记住,原始流都是 ASCII 数据!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
谁有同时解决这两个问题的好方法?我不确定这是否可能,除了对应用了不同规则的数据进行两次转换并比较结果之外。但是,如果您采用这种方法,您信任哪个输出?似乎 ASCII 启发式算法是关于最佳解决方案的,但是对于像病毒扫描程序这样复杂的东西,该代码实际上参与其中会增加多少代码、执行时间和复杂性?您将如何训练启发式引擎来了解什么是可接受的 Base64,什么不是?
更新:
对于这个问题继续获得的视图数量,我决定发布我在 C# 应用程序中使用了 3 年的简单 RegEx,其中包含数十万个事务。老实说,我最喜欢Gumbo给出的答案,这也是我选择它作为选择答案的原因。但是对于任何使用 C# 并且正在寻找一种非常快速的方法来至少检测字符串或字节 [] 是否包含有效的 Base64 数据的人,我发现以下内容对我来说非常有效。
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
是的,这仅适用于 Base64 数据的 STRING,而不是格式正确的 RFC1341 消息。因此,如果您正在处理这种类型的数据,请在尝试使用上述 RegEx 之前考虑到这一点。如果您正在处理 Base16、Base32、Radix 甚至 Base64 用于其他目的(URL、文件名、XML 编码等),那么强烈建议您阅读 RFC4648 @987654324 @ 在他的回答中提到,因为在尝试使用此问题/答案集中的建议之前,您需要充分了解实现使用的字符集和终止符。
【问题讨论】:
-
我猜你必须更好地定义任务。完全不清楚您的目标是什么:严格?解析 100% 的样本? ...
-
你的第一个例子应该是'VGhpcyBpcyBhIHNpbXBsZSBBU0NJSSBCYXNlNjQgZXhhbXBsZSBmb3IgU3RhY2tPdmVyZmxvdy4='
-
为什么不使用您的语言的标准解决方案?为什么需要基于正则表达式的手写解析器?
-
好问题。尽管我尝试了 UPDATE 正则表达式,方法是针对 NPM 和 it failed 返回的 base64 编码的 SHA 运行它,而所选答案中的正则表达式 works just fine。
-
不确定 UPDATE 正则表达式是如何在没有更正的情况下发布的,但看起来作者 打算 将
^放在括号外,作为起始锚。然而,一个更好的正则表达式,而不像接受的答案那样复杂,将是^[-A-Za-z0-9+/]*={0,3}$
标签: regex base64 standards-compliance rfc