Вопрос

Я продолжаю получать ошибку недопустимого символа 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" в конце, но я не думаю, что это вообще что-то делает, даже обрезанная она все равно выдает).Я даже скопировал и вставил всю строку в тестовый метод и сжал / распаковал ее.Работает нормально.

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

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

Это было полезно?

Решение

Ты говоришь

Строка - это именно то, что было записано в файл (с добавлением "\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' и символы '+' и '/'.

Другие советы

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

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

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

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

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

string stringToDecrypt = HttpContext.Current.Request.QueryString.ToString()

//изменить на строка stringToDecrypt = HttpUtility.UrlDecode(HttpContext.Current.Запрос.Строка запроса.toString())

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top