Строка Base64, выбрасывающая недопустимый символ ошибки - PullRequest
13 голосов
/ 02 апреля 2009

Я получаю ошибку недопустимого символа Base64, хотя не должен был.

Программа берет файл XML и экспортирует его в документ. Если пользователь захочет, он также сожмет файл. Сжатие работает нормально и возвращает строку Base64, которая закодирована в UTF-8 и записана в файл.

Когда пришло время перезагрузить документ в программу, я должен проверить, сжат ли он или нет, код просто:

byte[] gzBuffer = System.Convert.FromBase64String(text);
return "1F-8B-08" == BitConverter.ToString(new List<Byte>(gzBuffer).GetRange(4, 3).ToArray());

Проверяет начало строки, чтобы увидеть, есть ли в ней код GZips.

Теперь дело в том, что все мои тесты работают. Я беру строку, сжимаю ее, распаковываю и сравниваю с оригиналом. Проблема в том, когда я получаю строку, возвращенную из набора записей ADO. Строка - это именно то, что было записано в файл (с добавлением символа «\ 0» в конце, но я не думаю, что он вообще что-то делает, даже обрезанный, он все равно выбрасывает). Я даже копирую и вставляю всю строку в тестовый метод и сжимаю / распаковываю это. Работает нормально.

Тесты пройдут, но код не сможет использовать ту же самую строку? Единственное отличие - вместо того, чтобы просто объявить обычную строку и передать ее, я получаю возвращенную из набора записей.

Есть идеи, что я делаю не так?

Ответы [ 5 ]

15 голосов
/ 02 апреля 2009

Вы говорите

Строка именно то, что было написано в файл (с добавлением "\ 0" в конце, но я не думаю, что даже делает что-нибудь).

Фактически, он что-то делает (он заставляет ваш код выдавать FormatException: «Недопустимый символ в строке Base-64»), потому что Convert.FromBase64String не учитывает «\ 0 "быть действительным символом Base64.

  byte[] data1 = Convert.FromBase64String("AAAA\0"); // Throws exception
  byte[] data2 = Convert.FromBase64String("AAAA");   // Works

Решение: избавиться от нулевого завершения. (Возможно, позвоните .Trim("\0"))

Примечания

Документы MSDN для Convert.FromBase64String говорят, что при

будет выдано FormatException

Длина s, игнорируя пробелы символов, не ноль или кратный из 4.

-или-

Неверный формат s. s содержит неосновные 64 символа, больше чем два символа заполнения, или не пробел символ среди символы заполнения.

и вот

Базовые 64 цифры в порядке возрастания с нуля прописные буквы От «A» до «Z», строчные буквы «a» до 'z', цифры от '0' до '9' и символы '+' и '/'.

3 голосов
/ 02 апреля 2009

Допустим ли нулевой символ или нет, зависит от рассматриваемого кодека base64. Учитывая неопределенность стандарта Base64 (нет точной официальной спецификации), многие реализации просто игнорируют его как пробел. И тогда другие могут пометить это как проблему. А глючные не заметят и с радостью попробуют расшифровать его ...: - /

Но звучит так, что реализации на c # это не нравится (это один из правильных подходов), поэтому, если удаление помогает, это должно быть сделано.

Один небольшой дополнительный комментарий: UTF-8 не является обязательным требованием, ISO-8859-x, также известный как Latin-x, и 7-битная Ascii также будут работать. Это потому, что Base64 был специально разработан для использования только 7-битного подмножества, которое работает со всеми 7-битными кодировками, совместимыми с ASCII.

0 голосов
/ 16 марта 2018
string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()

// изменить на string stringToDecrypt = HttpUtility.UrlDecode (HttpContext.Current.Request.QueryString.ToString ())

0 голосов
/ 16 мая 2012

Одна вещь, связанная с преобразованием Base64 из строки, заключается в том, что некоторые функции преобразования используют предыдущие «data: image / jpg; base64», а другие принимают только фактические данные.

0 голосов
/ 02 апреля 2009

Если удаление \ 0 из конца строки невозможно, вы можете добавить свой собственный символ для каждой кодируемой строки и удалить его при декодировании.

...