确定字符串是否经过两次Base64编码

9

有没有办法确定字符串是否经过两次base64编码?

例如,我能否使用带有preg_match函数的正则表达式模式来判断这一点?


我认为你得到了负评,因为这个问题有点偏离主题,并需要花费很多精力来回答;在回答一个不应该被问出的问题时投入大量精力会激怒人们。下次提问时,请尽量避免X-Y问题 - sshine
1个回答

13

(实用回答。)不要使用正则表达式。使用 base64_decode() 函数并将其可选的$strict参数设置为true,以查看它是否符合您期望的格式。或者尝试多次解码它,直到它无法再解码为止。例如:

function base64_decode_multiple(string $data, int $count = 2) {
    while ($count-- > 0 && ($decoded = base64_decode($data, true)) !== false) {
        $data = $decoded;
    }
    return $data;
}

(理论答案。) 双64进制编码字符串是规则的,因为有限数量的字节序列可以正确地将一个64进制编码的消息进行编码。

你只需要验证每组四个字符,就可以一次性检查是否有东西被编码成了64进制。由于使用=作为填充符号,因此在64进制编码的消息中,最后四个字节可能是特殊情况。使用正则表达式:

<char>           := [A-Za-z0-9+/]
<end-char>       := [A-Za-z0-9+/=]
<chunk>          := <char>{4}
<end-chunk>      := <char>{2} <end-char>{2} | <char>{3} <end-char>
<base64-encoded> := <chunk>* <end-chunk>?

使用正则表达式也可以判断某个内容是否已经进行了两次base64编码,但这并不是一个简单或优美的解决方案,因为一次仅仅检查4个字节是不够的。

例如:"QUFBQQ==" 经过base64解码后得到 "AAAA" ,再次base64解码后得到3个NUL字节。

$ echo -n "QUFBQQ==" | base64 -d | xxd
00000000: 4141 4141                                AAAA

$ echo -n "AAAA" | base64 -d | xxd
00000000: 0000 00                                  ...

此时,我们可以列举出所有双重Base64编码,其中Base64编码是在Base64字母表中4个字节(“AAAA”,“AAAB”,“AAAC”,“AAAD”等),并将其最小化:

<ugly 4> := QUFBQQ== | QUFBQg== | QUFBQw== | QUFBRA== | ...

我们可以列举所有双重Base64编码的前4个字节,其中Base64编码为8个或更长的字节(不涉及使用=填充的情况),并将其最小化:

<chunk 4> := QUFB | QkFB | Q0FB | REFB | ...

双重base64编码字符串的一个分区(漂亮的那个)不会在末尾包含=符号;它们的长度是8的倍数:

<pretty double-base64-encoded> := <chunk 4>{2}*

另一种双重base64编码字符串的分割方式将具有长度为4的倍数但不是8(4、12、20等)的长度;它们可以被视为在末尾有一个丑陋比特的漂亮字符串:

<ugly double-base64-encoded> := <chunk 4>{2}* <ugly 4>

我们可以构建一个组合的正则表达式:

<double-base64-encoded> := <pretty double-base64-encoded>
                         | <ugly double-base64-encoded>

就像你不想检查一个整数是否在某个有限区间内一样,我说过,你可能不想因为双重Base64编码的消息是正常的而经历所有这些麻烦。此外,这是一个得到错误答案时应该问另一个问题的好例子。:-)


你有没有想过如何使用Java实现多重解码,而不是使用PHP?我认为我面临着一个类似的问题,即服务器返回双重编码的base64数据,但我还没有成功地进行双重解码。你可以在这里阅读更多信息:https://stackoverflow.com/questions/69797789/base64-encoded-image-is-null-when-decoded?noredirect=1#comment123378162_69797789。 - Uche Ozoemena

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接