2009-04-02 23 views
13

Continuo a ricevere un errore di carattere non valido Base64 anche se non dovrei.Base64 Lancio di caratteri non validi errore

Il programma acquisisce un file XML e lo esporta in un documento. Se l'utente vuole, comprimerà anche il file. La compressione funziona correttamente e restituisce una stringa Base64 che è codificata in UTF-8 e scritta in un file.

Quando è il momento di ricaricare il documento nel programma devo controllare se il suo compresso o meno, il codice è semplicemente:

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

controlla l'inizio della stringa per vedere se ha il codice gzip dentro.

Ora il fatto è che tutti i miei test funzionano. Prendo una stringa, comprimilo, lo decomprimo e lo paragono all'originale. Il problema è quando ottengo la stringa restituita da un Recordset ADO. La stringa è esattamente ciò che è stato scritto nel file (con l'aggiunta di un "\ 0" alla fine, ma non penso che faccia nulla, anche se ritagliato ancora getta). Ho persino copiato e incollato l'intera stringa in un metodo di prova e compresso/decompresso. Funziona bene.

I test passeranno ma il codice non funzionerà utilizzando la stessa stringa esatta? L'unica differenza è invece di dichiarare una stringa normale e passarla viene restituita da un recordset.

Qualche idea su cosa sto sbagliando?

+0

Probabilmente sarebbe utile se si pubblicasse un esempio di una stringa che si sta passando a Convert.FromBase64String (ad esempio cosa si ottiene in uscita se si mette un Debug.Write direttamente prima della chiamata) –

+0

... pari se hai postato il primo e l'ultimo 8 o più byte e la lunghezza della stringa, questo sarebbe probabilmente sufficiente per vedere che la stringa è il formato corretto. –

+0

qGcAAB + LCA ... cAAA == Ha una lunghezza di 2376 caratteri. – Brandon

risposta

15

Tu dici

La stringa è esattamente ciò che è stato scritto al file (con l'aggiunta di un "\ 0" alla fine, ma non credo che fa ancora nulla) .

In realtà, lo fa fare qualcosa (che provoca il codice per lanciare una FormatException: "Carattere non valido in una stringa Base64"), perché il Convert.FromBase64String non considera "\ 0" di essere un personaggio Base64 valida .

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

Soluzione: eliminare la terminazione zero. (Forse chiamare .Trim("\0"))

Note:

Il MSDN docs for Convert.FromBase64String dicono che lancerà una FormatException quando

La lunghezza di s, ignorando lo spazio bianco caratteri, non è zero o un multiplo di 4.

-or-

Il formato di s non è valido. s contiene un carattere non base di 64, più di due caratteri di riempimento o un carattere di spazio non bianco tra i caratteri di riempimento .

e che

La base 64 cifre in ordine ascendente da zero sono i caratteri maiuscoli 'A' a 'Z', caratteri minuscoli 'a' a 'z', numeri ' Da 0 'a' 9 'e i simboli ' + 'e'/'.

+0

Ho tagliato il \ 0, getta ancora. – Brandon

+0

Getta ancora un FormatException o qualcos'altro? Qual è la stringa esatta inviata a FromBase64String? –

+0

La stringa esatta è un po 'lunga da postare. C'è un limite di dimensioni che non conosco? Ciò che è lì è valido, l'ho controllato per qualsiasi carattere non consentito in Base64. Forse ho sbagliato il trim, anche se non spiega perché i test stanno andando bene. – Brandon

3

Se il char nullo è consentito o non dipende realmente dal codec di base64 in questione. Data la vaghezza dello standard Base64 (non esiste una specifica esatta autorevole), molte implementazioni lo ignorerebbero semplicemente come spazio bianco. E poi altri possono segnalarlo come un problema. E quelli più insignificanti non se ne accorgerebbero e proverebbero volentieri a decodificarlo ...: -/

Ma sembra che l'implementazione C# non gli piaccia (che è un approccio valido) quindi se la rimozione aiuta, dovrebbe essere fatto.

Un piccolo commento aggiuntivo: UTF-8 non è un requisito, ISO-8859-x alias Latin-x e Ascii a 7 bit funzionerebbe anche. Questo perché Base64 è stato specificamente progettato per utilizzare solo sottoinsiemi a 7 bit che funziona con tutte le codifiche ASCII compatibili a 7 bit.

0

Se la rimozione di \ 0 dalla fine della stringa è impossibile, è possibile aggiungere il proprio carattere per ogni stringa codificata e rimuoverlo in decodifica.

0

Una cosa da fare con la conversione di Base64 da una stringa è che alcune funzioni di conversione utilizzano il precedente "data: image/jpg; base64" e altri accettano solo i dati effettivi.

Problemi correlati