2009-04-02 40 views
13

Sigo recibiendo un error de carácter inválido de Base64 aunque no debería.Base64 String arrojando error de carácter no válido

El programa toma un archivo XML y lo exporta a un documento. Si el usuario lo desea, comprimirá el archivo también. La compresión funciona bien y devuelve una Cadena Base64 codificada en UTF-8 y escrita en un archivo.

Cuando es hora de volver a cargar el documento en el programa que tengo que comprobar si su comprimido o no, el código es simplemente:

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

comprueba el principio de la cadena para ver si tiene el código gzips en eso.

Ahora sí, todas mis pruebas funcionan. Tomo una cuerda, la comprime, la descomprimo y la comparo con el original. El problema es cuando obtengo la cadena devuelta desde un conjunto de registros ADO. La cadena es exactamente lo que se escribió en el archivo (con la adición de un "\ 0" al final, pero no creo que, incluso, haga algo, incluso recortarlo). Incluso copio y pegué toda la cadena en un método de prueba y comprimir/descomprimir eso. Funciona bien.

¿Las pruebas pasarán pero el código fallará usando exactamente la misma cadena? La única diferencia es que en lugar de simplemente declarar una cadena regular y pasarla, obtengo una devuelta de un conjunto de registros.

¿Alguna idea sobre qué estoy haciendo mal?

+0

Probablemente sería útil publicar un ejemplo de una cadena que está pasando a Convert.FromBase64String (por ejemplo, lo que obtiene en el resultado si coloca un Debug.Write directamente antes de la llamada) –

+0

... incluso si publicó los primeros y últimos 8 o más bytes, y la longitud de la cadena, eso probablemente sería suficiente para ver que la cadena es del formato correcto. –

+0

qGcAAB + LCA ... cAAA == Sus 2376 caracteres de largo. – Brandon

Respuesta

15

Usted dice

La cadena es exactamente lo que estaba escrito al archivo (con la adición de un "\ 0" al final, pero no creo que incluso hace nada) .

De hecho, se hace algo (que hace que su código para lanzar una FormatException: "Carácter no válido en una cadena Base64") debido a que el Convert.FromBase64String no considera "\ 0" a ser un personaje Base64 válida .

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

Solución: Se puede olvidarse de la terminación cero. (Tal vez llame .Trim("\0"))

Notas:

El MSDN docs for Convert.FromBase64String dicen que va a lanzar una FormatException cuando

La longitud de s, ignorando espacios en blanco caracteres, no es cero o un múltiplo de 4.

-o bien -

El formato de s no es válido. s contiene un carácter no base 64, más que dos caracteres de relleno, o un carácter de espacio no blanco entre los caracteres de relleno .

y que

La base 64 dígitos en orden ascendente de cero son los caracteres en mayúsculas 'A' a 'Z', los caracteres en minúsculas 'a' a 'z', números ' 0 'a' 9 ', y los símbolos ' + 'y'/'.

+0

Recorto el \ 0 apagado, todavía lanza. – Brandon

+0

¿Todavía arroja una FormatException, o algo más? ¿Cuál es la cadena exacta que se pasa a FromBase64String? –

+0

La cadena exacta es un poco larga para publicar. ¿Hay un límite de tamaño que no sepa? Sin embargo, lo que hay es válido, lo revisé en busca de cualquier carácter no permitido en Base64. Tal vez simplemente hice el ajuste incorrecto, aunque no explica por qué las pruebas funcionan bien. – Brandon

3

Si el carácter nulo está permitido o no realmente depende del códec base64 en cuestión. Dada la vaguedad del estándar Base64 (no hay una especificación exacta autorizada), muchas implementaciones simplemente lo ignorarían como espacio en blanco. Y luego otros pueden señalarlo como un problema. Y los más caprichosos no se darían cuenta y felizmente tratarían de decodificarlo ...: -/

Pero parece que a la implementación de C# no le gusta (que es un enfoque válido) así que si eliminarlo ayuda, debería hacerse.

Un pequeño comentario adicional: UTF-8 no es un requisito, ISO-8859-x aka Latin-x, y 7-bit Ascii también funcionaría. Esto porque Base64 fue diseñado específicamente para usar solo un subconjunto de 7 bits que funciona con todas las codificaciones compatibles con ascii de 7 bits.

0

Si es imposible eliminar \ 0 del final de la cadena, puede agregar su propio carácter para cada cadena que codifique y eliminarlo en la decodificación.

0

Uno de los puntos a tener en cuenta al convertir Base64 de una cadena es que algunas funciones de conversión utilizan los "datos: image/jpg; base64" anteriores, y otras solo aceptan los datos reales.

Cuestiones relacionadas