Est-il possible d'utiliser un RegEx pour valider ou nettoyer les données Base64? C'est la question simple, mais ce sont les facteurs qui motivent cette question qui la rendent difficile.
J'ai un décodeur Base64 qui ne peut pas entièrement compter sur les données d'entrée pour suivre les spécifications RFC. Donc, les problèmes auxquels je suis confronté sont des problèmes comme peut-être les données Base64 qui ne peuvent pas être divisées en 78 (je pense que c'est 78, je devrais vérifier la RFC, alors ne me dites pas si le nombre exact est faux) lignes, ou que les lignes peuvent ne pas se terminer par CRLF; en ce qu 'il peut n'avoir qu'un CR, ou LF, ou peut-être aucun.
Donc, j'ai eu un sacré temps à analyser les données Base64 formatées comme telles. Pour cette raison, des exemples tels que les suivants deviennent impossibles à décoder de manière fiable. Je n'afficherai que des en-têtes MIME partiels par souci de concision.
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Ok, donc l'analyse n'est pas un problème, et c'est exactement le résultat auquel on s'attend. Et dans 99% des cas, l'utilisation de n'importe quel code pour au moins vérifier que chaque caractère du tampon est un caractère base64 valide fonctionne parfaitement. Mais, l'exemple suivant jette une clé dans le mélange.
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
C'est une version de l'encodage Base64 que j'ai vu dans certains virus et autres choses qui tentent de profiter du désir de certains lecteurs de messagerie d'analyser le mime à tout prix, par rapport à ceux qui se conforment strictement au livre, ou plutôt à RFC; si vous voulez.
Mon décodeur Base64 décode le deuxième exemple en flux de données suivant. Et gardez à l'esprit ici, le flux d'origine est constitué de toutes les 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 même possible, en dehors de faire deux transformations sur les données avec des règles différentes appliquées, et de comparer les résultats. Cependant, si vous avez adopté cette approche, à quel résultat faites-vous confiance? Il semble que l'heuristique ASCII soit la meilleure solution, mais combien de code supplémentaire, de temps d'exécution et de complexité cela ajouterait-il à quelque chose d'aussi compliqué qu'un antivirus, dans lequel ce code est réellement impliqué? Comment entraîneriez-vous le moteur heuristique pour savoir ce qui est acceptable en Base64 et ce qui ne l'est pas?
METTRE À JOUR:
Compte tenu du nombre de vues que cette question continue d'obtenir, 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 le mieux la réponse donnée par Gumbo , c'est pourquoi je l'ai choisie comme réponse choisie. Mais pour quiconque utilise C # et cherche un moyen très rapide de détecter au moins si une chaîne ou un octet [] contient des données Base64 valides ou non, j'ai trouvé que ce qui suit fonctionnait très bien pour moi.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
Et oui, c'est juste pour une STRING de données Base64, PAS un message RFC1341 correctement formaté . Donc, si vous traitez avec des données de ce type, veuillez en tenir compte avant d'essayer d'utiliser le RegEx ci-dessus. Si vous faites affaire avec Base16, Base32, Radix ou même base64 à d' autres fins (URL, noms de fichiers, XML d' encodage, etc.), il est fortement recommandé de lire RFC4648 qui Gumbo mentionné dans sa réponse que vous devez être bien conscient du jeu de caractères et des terminateurs utilisés par l'implémentation avant d'essayer d'utiliser les suggestions de cet ensemble de questions / réponses.