Можно ли использовать RegEx для проверки или очистки данных Base64? Это простой вопрос, но факторы, которые приводят к этому вопросу, усложняют его.
У меня есть декодер Base64, который не может полностью полагаться на входные данные в соответствии со спецификациями RFC. Итак, проблемы, с которыми я сталкиваюсь, - это такие проблемы, как, возможно, данные 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, которую я видел в некоторых вирусах и других вещах, которые пытаются использовать в своих интересах желание некоторых почтовых читателей анализировать пантомиму любой ценой по сравнению с теми, которые действуют строго по книге или, скорее, RFC; если вы будете.
Мой декодер Base64 декодирует второй пример в следующий поток данных. И имейте в виду, что исходный поток - это все данные ASCII!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
У кого-нибудь есть хороший способ решить обе проблемы сразу? Я не уверен, что это вообще возможно, кроме выполнения двух преобразований данных с разными применяемыми правилами и сравнения результатов. Однако если вы выбрали такой подход, какому результату вы доверяете? Кажется, что эвристика ASCII - лучшее решение, но насколько больше кода, времени выполнения и сложности это добавит к чему-то столь же сложному, как антивирусный сканер, в котором этот код фактически задействован? Как бы вы обучили эвристический движок, чтобы узнать, что приемлемо для Base64, а что нет?
ОБНОВИТЬ:
Что касается количества просмотров, которые продолжает получать этот вопрос, я решил опубликовать простой RegEx, который я использую в приложении C # уже 3 года, с сотнями тысяч транзакций. Честно говоря, мне больше всего нравится ответ Гамбо , поэтому я выбрал его в качестве выбранного ответа. Но для всех, кто использует C # и ищет очень быстрый способ, по крайней мере, определить, содержит ли строка или byte [] действительные данные Base64 или нет, я обнаружил, что следующее очень хорошо работает для меня.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
И да, это только для STRING данных Base64, а не правильно отформатированный RFC1341 сообщения. Итак, если вы имеете дело с данными этого типа, пожалуйста, примите это во внимание, прежде чем пытаться использовать вышеуказанный RegEx. Если вы имеете дело с Base16, Base32, корном или даже Base64 для других целей (URL - адреса, имена файлов, XML кодирование и т.д.), то он настоятельно рекомендую вам прочитать RFC4648 , что Гамбо упомянул в своем ответе , как вы должны быть хорошо знать кодировку и терминаторы, используемые реализацией, прежде чем пытаться использовать предложения в этом наборе вопросов / ответов.
источник
^
за скобки в качестве начальной привязки. Однако гораздо лучшим регулярным выражением, не усложняющим принятый ответ, было бы^[-A-Za-z0-9+/]*={0,3}$
Ответы:
Из RFC 4648 :
Таким образом, это зависит от цели использования закодированных данных, следует ли считать данные опасными.
Но если вы просто ищете регулярное выражение, соответствующее словам в кодировке Base64, вы можете использовать следующее:
источник
name
это действительная кодировка Base64 (шестнадцатеричной) байтовой последовательности9d a9 9e
.^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$
должен избежать негативной реакцииЭто хорошо, но будет соответствовать пустой строке
Это не соответствует пустой строке:
источник
MQ==
AQENVg688MSGlEgdOJpjIUC=
это действительная форма.=
. Последний?
допускает 0=
. Замена на{1}
требует 1 или 2 концовки=
Ни « : », ни « . » Не будут отображаться в допустимом Base64, поэтому я думаю, что вы можете однозначно выбросить
http://www.stackoverflow.com
строку. В Perl, скажем, что-то вродеможет быть то, что вы хотите. Он производит
Это простой пример ASCII Base64 для StackOverflow.
источник
Лучшее регулярное выражение, которое я мог найти до сих пор, находится здесь https://www.npmjs.com/package/base64-regex
который в текущей версии выглядит так:
источник
\\n?
.Чтобы проверить изображение base64, мы можем использовать это регулярное выражение
источник
Вот альтернативное регулярное выражение:
Он удовлетворяет следующим условиям:
(?=^(.{4})*$)
[A-Za-z0-9+/]*
={0,2}
источник