2009-04-02 7 views
13

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

Программа принимает 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

Возможно, это поможет, если вы разместите пример строки, которую вы передаете в Convert.FromBase64String (например, что вы получаете на выходе, если вы положили Debug.Write непосредственно перед вызовом) –

+0

... даже если вы отправили первый и последний 8 или около того байты и длину строки, это, вероятно, было бы достаточно, чтобы увидеть, что строка является правильным форматом. –

+0

qGcAAB + LCA ... cAAA == Его 2376 символов. – Brandon

ответ

15

Вы говорите

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

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

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

Решение: Избавьтесь от прекращения нулевой. (Может позвонить .Trim("\0"))

Примечания:

MSDN docs for Convert.FromBase64String говорят, что будет бросать FormatException когда

Длина с, игнорируя Пустое пространство символов, не равна нулю или кратна из 4.

-или-

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

и что

Основания 64 цифр в порядке возрастания от нуля являются символами верхнего регистра 'A' до 'Z', строчных символов 'а' на 'Z', цифры ' 0 '-' 9 ', а символы ' + 'и'/'.

+0

Я обрезаю \ 0, он все равно бросает. – Brandon

+0

Он по-прежнему бросает исключение FormatException или что-то еще? Какая строка передается в FromBase64String? –

+0

Точная строка немного длинная для публикации. Есть ли ограничение по размеру, о котором я не знаю? Тем не менее, я проверял его для любых символов, которые не разрешены в Base64. Может быть, я просто сделал неправильно, хотя это не объясняет, почему тесты работают нормально. – Brandon

3

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

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

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

0

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

0

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