





(Практический ответ.) Не использовать регулярное выражение. Расшифруйте вашу строку с помощью необязательного параметра 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;
}
(Теоретический ответ.) Строки с двойной кодировкой base64 находятся регулярно, потому что существует конечное количество байтовых последовательностей, которые должным образом кодируют base64 сообщение с кодировкой base64.
Вы можете проверить, является ли что-то однажды в кодировке base64, поскольку вы можете проверить каждый набор из четырех символов. Последние четыре байта в сообщении с кодировкой base64 могут быть особым случаем, потому что = используются в качестве заполнения. Используя регулярное выражение:
<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-декодирует до трех NUL-байтов:
$ echo -n "QUFBQQ= = " | base64 -d | xxd
00000000: 4141 4141 AAAA
$ echo -n "AAAA" | base64 -d | xxd
00000000: 0000 00 ...
На этом этапе мы могли бы перечислить все кодировки double-base64, где кодировка base64 составляет 4 байта в алфавите base64 («AAAA», «AAAB», «AAAC», «AAAD» и т. д.) И минимизировать это:
<ugly 4> := QUFBQQ== | QUFBQg== | QUFBQw== | QUFBRA== | ...
И мы могли бы перечислить первые 4 байта всех кодировок double-base64, где кодировка 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 находятся обычны. Точно так же, как вы не хотите проверять, находится ли целое число в каком-то конечном интервале. Кроме того, это хороший пример неправильного ответа, когда вы должны были задать другой вопрос. :-)
Я думаю, вы получили отрицательные голоса, потому что вопрос был немного неверно направлен и требовал больших усилий для ответа; приложить много усилий, чтобы ответить на вопрос, который не следовало задавать, разозлит людей. В следующий раз, когда вы зададите вопрос, постарайтесь избежать XY проблема.