È possibile utilizzare una RegEx per convalidare o disinfettare i dati Base64? Questa è la semplice domanda, ma i fattori che guidano questa domanda sono ciò che la rendono difficile.
Ho un decoder Base64 che non può fare completamente affidamento sui dati di input per seguire le specifiche RFC. Quindi, i problemi che devo affrontare sono problemi come forse i dati Base64 che potrebbero non essere suddivisi in 78 (penso sia 78, dovrei ricontrollare l'RFC, quindi non chiamarmi se il numero esatto è sbagliato) righe, o che le righe non possono finire in CRLF; in quanto può avere solo una CR, o LF, o forse nessuno dei due.
Quindi, mi sono divertito un mondo ad analizzare i dati Base64 formattati come tali. A causa di ciò, esempi come i seguenti diventano impossibili da decodificare in modo affidabile. Visualizzerò solo intestazioni MIME parziali per brevità.
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Ok, quindi l'analisi non è un problema ed è esattamente il risultato che ci aspetteremmo. E nel 99% dei casi, l'utilizzo di qualsiasi codice per verificare almeno che ogni carattere nel buffer sia un carattere base64 valido, funziona perfettamente. Ma il prossimo esempio getta una chiave nel mix.
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Questa è una versione della codifica Base64 che ho visto in alcuni virus e altre cose che tentano di trarre vantaggio dal desiderio di alcuni lettori di posta di analizzare mime a tutti i costi, contro quelli che seguono rigorosamente il libro, o meglio RFC; se vorrai.
Il mio decodificatore Base64 decodifica il secondo esempio nel seguente flusso di dati. E tieni presente che lo stream originale è tutto di dati ASCII!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
Qualcuno ha un buon modo per risolvere entrambi i problemi contemporaneamente? Non sono nemmeno sicuro che sia possibile, a parte fare due trasformazioni sui dati con regole diverse applicate e confrontare i risultati. Tuttavia, se hai adottato questo approccio, di quale output ti fidi? Sembra che l'euristica ASCII sia la soluzione migliore , ma quanto più codice, tempo di esecuzione e complessità aggiungerebbero a qualcosa di complicato come uno scanner antivirus, in cui è effettivamente coinvolto questo codice? Come addestreresti il motore euristico per apprendere cosa è Base64 accettabile e cosa no?
AGGIORNARE:
Considerando il numero di visualizzazioni che questa domanda continua a ottenere, ho deciso di pubblicare la semplice RegEx che utilizzo in un'applicazione C # da 3 anni, con centinaia di migliaia di transazioni. Onestamente, mi piace di più la risposta data da Gumbo , motivo per cui l'ho scelta come risposta selezionata. Ma per chiunque utilizzi C # e cerchi un modo molto rapido per rilevare almeno se una stringa o un byte [] contiene dati Base64 validi o meno, ho trovato che quanto segue funziona molto bene per me.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
E sì, questo è solo per una STRINGA di dati Base64, NON un messaggio RFC1341 formattato correttamente . Quindi, se hai a che fare con dati di questo tipo, ti preghiamo di tenerne conto prima di tentare di utilizzare la RegEx sopra. Se hai a che fare con Base16, Base32, Radix o anche Base64 per altri scopi (URL, nomi di file, codifica XML, ecc.), Ti consigliamo vivamente di leggere RFC4648 che Gumbo ha menzionato nella sua risposta perché devi stare bene consapevole del set di caratteri e dei terminatori utilizzati dall'implementazione prima di tentare di utilizzare i suggerimenti in questo set di domande / risposte.
^
esterno delle parentesi, come punto di ancoraggio iniziale. Tuttavia, una regex molto migliore, senza complicarsi come la risposta accettata, sarebbe^[-A-Za-z0-9+/]*={0,3}$