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.
la source
^
les parenthèses en dehors des crochets, comme point d'ancrage de départ. Cependant, une bien meilleure regex, sans devenir aussi compliquée que la réponse acceptée, serait^[-A-Za-z0-9+/]*={0,3}$
Réponses:
De la RFC 4648 :
Cela dépend donc du but de l'utilisation des données codées si les données doivent être considérées comme dangereuses.
Mais si vous recherchez simplement une expression régulière correspondant à des mots encodés en Base64, vous pouvez utiliser ce qui suit:
la source
name
s'agit d'un codage Base64 valide de la séquence d'octets (hexadécimal)9d a9 9e
.^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$
doit échapper au contrecoupCelui-ci est bon, mais correspondra à une chaîne vide
Celui-ci ne correspond pas à une chaîne vide:
la source
MQ==
ne pas correspondre à votre expressionAQENVg688MSGlEgdOJpjIUC=
est la forme valide.=
. Le dernier?
autorise 0=
. Le remplacer par{1}
nécessite 1 ou 2 fin=
Ni un " : " ni un " . " N'apparaîtront dans Base64 valide, donc je pense que vous pouvez sans ambiguïté jeter la
http://www.stackoverflow.com
ligne. En Perl, disons, quelque chose commepourrait être ce que vous voulez. Cela produit
Il s'agit d'un exemple simple ASCII Base64 pour StackOverflow.
la source
La meilleure expression rationnelle que j'ai pu trouver jusqu'à présent est ici https://www.npmjs.com/package/base64-regex
qui est dans la version actuelle ressemble à:
la source
\\n?
.Pour valider l' image base64, nous pouvons utiliser cette regex
la source
Voici une autre expression régulière:
Il satisfait aux conditions suivantes:
(?=^(.{4})*$)
[A-Za-z0-9+/]*
={0,2}
la source