Est-il possible d'utiliser un RegEx pour valider ou assainir des données Base64 ? C'est une question simple, mais les facteurs qui la motivent la rendent difficile.
J'ai un décodeur Base64 qui ne peut pas se fier entièrement aux données d'entrée pour suivre les spécifications RFC. Ainsi, les problèmes auxquels je suis confronté sont des problèmes tels que des données Base64 qui peuvent ne pas être divisées en 78 (je pense que c'est 78, il faudrait que je vérifie le RFC, alors ne me faites pas de reproches si le nombre exact est erroné) lignes de caractères, ou que les lignes peuvent ne pas se terminer par CRLF ; en ce sens qu'elles peuvent n'avoir qu'un CR, ou LF, ou peut-être ni l'un, ni l'autre.
J'ai donc eu beaucoup de mal à analyser les données Base64 formatées comme telles. De ce fait, des exemples comme celui-ci deviennent impossibles à décoder de manière fiable. Par souci de concision, je n'afficherai que des en-têtes MIME partiels.
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Ok, l'analyse n'est pas un problème, et c'est exactement le résultat que nous attendions. Et dans 99% des cas, l'utilisation d'un code pour au moins vérifier que chaque caractère dans le tampon est un caractère base64 valide, fonctionne parfaitement. Mais l'exemple suivant jette un pavé dans la mare.
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Il s'agit d'une version de l'encodage Base64 que j'ai vue dans certains virus et autres choses qui tentent de profiter du désir de certains lecteurs de courrier d'analyser le mime à tout prix, par opposition à ceux qui suivent strictement les règles, ou plutôt les RFC, si vous voulez.
Mon décodeur Base64 décode le deuxième exemple en un flux de données. N'oubliez pas que le flux d'origine est constitué de données ASCII !
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
Quelqu'un a-t-il un bon moyen de résoudre les deux problèmes à la fois ? Je ne suis pas sûr que ce soit possible, si ce n'est en effectuant deux transformations sur les données avec des règles différentes, et en comparant les résultats. Cependant, si vous adoptez cette approche, à quel résultat faites-vous confiance ? Il semble que l'heuristique ASCII soit à peu près la plus fiable. meilleur mais combien de code, de temps d'exécution et de complexité supplémentaires cela ajouterait-il à quelque chose d'aussi compliqué qu'un scanner de virus, dans lequel ce code est en fait impliqué ? Comment entraîner le moteur heuristique à apprendre ce qui est acceptable en Base64 et ce qui ne l'est pas ?
UPDATE :
Vu le nombre de vues que cette question continue de recevoir, j'ai décidé de publier le simple RegEx que j'utilise dans une application C# depuis 3 ans maintenant, avec des centaines de milliers de transactions. Honnêtement, j'aime la réponse donnée par Gumbo le meilleur, c'est pourquoi je l'ai choisi comme réponse sélectionnée. Mais pour tous ceux qui utilisent C# et qui cherchent un moyen très rapide de détecter au moins si une chaîne de caractères ou un octet[] contient des données Base64 valides ou non, j'ai trouvé ce qui suit qui fonctionne très bien pour moi.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
Et oui, c'est juste pour une CHAÎNE de données Base64, PAS d'un fichier correctement formaté. RFC1341 message. Par conséquent, si vous traitez des données de ce type, tenez-en compte avant d'essayer d'utiliser le RegEx ci-dessus. Si vous avez affaire à des données en Base16, Base32, Radix ou même Base64 à d'autres fins (URL, noms de fichiers, encodage XML, etc.), il est possible d'utiliser le RegEx suivant très vous recommande de lire RFC4648 que Gumbo mentionné dans sa réponse, car vous devez bien connaître le jeu de caractères et les terminateurs utilisés par l'implémentation avant d'essayer d'utiliser les suggestions de cette série de questions/réponses.