Есть ли способ в C # проверить, закодирована ли строка в Base 64, кроме попытки ее преобразовать и увидеть, есть ли ошибка? У меня есть такой код:
// Convert base64-encoded hash value into a byte array.
byte[] HashBytes = Convert.FromBase64String(Value);
Я хочу избежать исключения «Недопустимый символ в строке Base-64», которое возникает, если значение не является допустимой строкой base 64. Я хочу просто проверить и вернуть false вместо обработки исключения, потому что я ожидаю, что иногда это значение не будет строкой с базой 64. Есть ли способ проверить перед использованием функции Convert.FromBase64String?
Спасибо!
Обновление:
спасибо за все ваши ответы. Вот метод расширения, который вы все можете использовать до сих пор, он, кажется, гарантирует, что ваша строка будет передавать Convert.FromBase64String без исключения. .NET, похоже, игнорирует все конечные и конечные пробелы при преобразовании в базу 64, поэтому "1234" является действительным, а также "1234"
public static bool IsBase64String(this string s)
{
s = s.Trim();
return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
Для тех, кто интересуется производительностью тестирования по сравнению с перехватом и исключением, в большинстве случаев для этой вещи с базой 64 быстрее проверить, чем перехватить исключение, пока вы не достигнете определенной длины. Чем меньше длина, тем быстрее она
В моем очень ненаучном тестировании: для 10000 итераций для длины символов 100000 - 110000 сначала было в 2,7 раза быстрее протестировать.
На 1000 итераций для символов длиной от 1 до 16 символов всего за 16 000 тестов это было в 10,9 раза быстрее.
Я уверен, что есть момент, когда становится лучше тестировать метод, основанный на исключениях. Я просто не знаю, в какой момент.
источник
=
знака. Если заполнение неверно, будет выдана ошибка, даже если ввод соответствует выражению.\n\fLE16
- ваш метод даст для этого ложное срабатывание. Для всех, кто читает и ищет надежный метод; Я бы порекомендовал перехватить FormatException или использовать подходящее RegEx, см. Stackoverflow.com/questions/475074/… .@"^[a-zA-Z0-9\+/]*={0,2}$"
Ответы:
Строку Base64 довольно легко распознать, так как она будет состоять только из символов
'A'..'Z', 'a'..'z', '0'..'9', '+', '/'
и часто дополняется в конце тремя знаками '=', чтобы длина была кратна 4. Но вместо того, чтобы сравнивать их, вы должны ' Лучше игнорировать исключение, если оно произойдет.источник
Используйте Convert.TryFromBase64String из C # 7.2
источник
Convert.TryFromBase64String(base64.PadRight(base64.Length / 4 * 4 + (base64.Length % 4 == 0 ? 0 : 4), '='), new Span<byte>(new byte[base64.Length]), out _)
. Спасибо.Я знаю, вы сказали, что не хотите ловить исключение. Но поскольку перехват исключения более надежен, я опубликую этот ответ.
Обновление: я обновил состояние благодаря ойбеку для дальнейшего повышения надежности.
источник
base64String.Contains
многократный вызов может привести к снижению производительностиbase64String
, если это большая строка.base64String== null || base64String.Length == 0
сstring.IsNullOrEmpty(base64String)
Я считаю, что регулярное выражение должно быть:
Соответствует только одному или двум конечным знакам '=', а не трем.
s
должна быть строка, которая будет проверяться.Regex
является частьюSystem.Text.RegularExpressions
пространства имен.источник
Почему бы просто не поймать исключение и не вернуть False?
Это позволяет избежать дополнительных накладных расходов в общем случае.
источник
Просто для полноты картины хочу предложить некоторую реализацию. Вообще говоря, Regex - дорогостоящий подход, особенно если строка большая (что случается при передаче больших файлов). При следующем подходе сначала пробуются самые быстрые способы обнаружения.
РЕДАКТИРОВАТЬ
Как предложил Сэм , вы также можете немного изменить исходный код. Он предлагает более эффективный подход к последнему этапу испытаний. Рутина
можно использовать для замены
if (!Base64Chars.Contains(value[i]))
строки наif (IsInvalid(value[i]))
Полный исходный код с улучшениями от Сэма будет выглядеть так (удаленные комментарии для ясности)
источник
Ответ должен зависеть от использования строки. Есть много строк, которые могут быть «действительными base64» в соответствии с синтаксисом, предложенным несколькими плакатами, но которые могут «правильно» декодироваться без исключения в мусор. Пример: строка 8char
Portland
является допустимой Base64. Какой смысл утверждать, что это действительный Base64? Я предполагаю, что в какой-то момент вы захотите узнать, что эта строка должна или не должна декодироваться в Base64.В моем случае у меня есть строки подключения к Oracle, которые могут быть в виде обычного текста, например:
или в base64 вроде
Мне просто нужно проверить наличие точки с запятой, потому что это доказывает, что это НЕ base64, что, конечно, быстрее, чем любой другой метод.
источник
Knibb Высокие правила футбола!
Это должно быть относительно быстро и точно, но я признаю, что не подвергал это тщательному тестированию, всего несколько.
Он избегает дорогостоящих исключений, регулярных выражений, а также избегает цикла по набору символов, вместо этого используя диапазоны ascii для проверки.
источник
источник
Я буду использовать так, чтобы мне не нужно было снова вызывать метод convert
источник
Декодировать, перекодировать и сравнить результат с исходной строкой
источник
Имхо, на самом деле это невозможно. Все опубликованные решения не подходят для таких строк, как "test" и так далее. Если они могут быть разделены на 4, не являются нулевыми или пустыми, и если они являются допустимым символом base64, они пройдут все тесты. Это может быть много строк ...
Таким образом, нет реального решения, кроме как знать, что это строка в кодировке base 64 . Я придумал следующее:
Я ожидаю, что декодированная строка начинается с определенной структуры, поэтому проверяю ее.
источник
Конечно. Просто убедитесь , что каждый персонаж находится в пределах
a-z
,A-Z
,0-9
,/
, или+
, и строка заканчивается==
. (По крайней мере, это наиболее распространенная реализация Base64. Вы можете найти некоторые реализации, в которых используются символы, отличные от последних двух символов/
или+
для них.)источник
Да, поскольку Base64 кодирует двоичные данные в строки ASCII с использованием ограниченного набора символов, вы можете просто проверить это с помощью этого регулярного выражения:
/ ^ [A-Za-z0-9 \ = \ + \ / \ с \ п] + $ / с
который гарантирует, что строка содержит только AZ, az, 0-9, '+', '/', '=' и пробелы.
источник
=
символ в конце. Если это заполнение недействительно, это неправильная кодировка base64, даже если она соответствует вашему регулярному выражению. Вы можете продемонстрировать это, найдя строку base 64 с 1 или 2=
в конце, удалив их и попытавшись декодировать.Я бы предложил создать регулярное выражение для выполнения этой работы. Вам нужно будет проверить что-то вроде этого: [a-zA-Z0-9 + / =] Вам также нужно будет проверить длину строки. Я не уверен в этом, но я почти уверен, что если что-то будет обрезано (кроме отступа "="), оно взорвется.
Или еще лучше проверьте этот вопрос о стеке
источник
У меня было очень похожее требование, когда я позволяю пользователю выполнять некоторые манипуляции с изображением в
<canvas>
элементе, а затем отправляю полученное изображение, полученное с помощью,.toDataURL()
на бэкэнд. Я хотел выполнить некоторую проверку сервера перед сохранением изображения и реализовалValidationAttribute
использование некоторого кода из других ответов:Как видите, я ожидаю строку типа image / png, которая по умолчанию возвращается
<canvas>
при использовании.toDataURL()
.источник
Проверить Base64 или обычную строку
public bool IsBase64Encoded (String str)
{
}
источник
Все ответы были объединены в 1 функцию, которая на 100% гарантирует точность результатов.
1) Используйте функцию, как показано ниже:
2) Ниже представлена функция:
источник
Мне нравится идея проверки на регулярное выражение. Регулярные выражения могут быть быстрыми и временами экономить накладные расходы на кодирование. В исходном запросе было обновление, которое делало именно это. Однако я считаю, что никогда не могу предположить, что строки не будут нулевыми. Я бы расширил функцию Extension, чтобы проверить исходную строку на наличие символов NULL или только пробелов.
источник