Existe-t-il un moyen en C # de voir si une chaîne est encodée en Base 64 autre que d'essayer de la convertir et de voir s'il y a une erreur? J'ai un code de code comme celui-ci:
// Convert base64-encoded hash value into a byte array.
byte[] HashBytes = Convert.FromBase64String(Value);
Je veux éviter l'exception «Caractère invalide dans une chaîne de base 64» qui se produit si la valeur n'est pas une chaîne de base 64 valide. Je veux simplement vérifier et renvoyer false au lieu de gérer une exception car je m'attends à ce que parfois cette valeur ne soit pas une chaîne de base 64. Existe-t-il un moyen de vérifier avant d'utiliser la fonction Convert.FromBase64String?
Merci!
Mise à jour:
Merci pour toutes vos réponses. Voici une méthode d'extension que vous pouvez tous utiliser jusqu'à présent, elle semble garantir que votre chaîne passera Convert.FromBase64String sans exception. .NET semble ignorer tous les espaces de fin et de fin lors de la conversion en base 64, donc "1234" est valide, tout comme "1234"
public static bool IsBase64String(this string s)
{
s = s.Trim();
return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
Pour ceux qui s'interrogent sur les performances des tests par rapport à la capture et à l'exception, dans la plupart des cas, pour cette chose de base 64, il est plus rapide de vérifier que d'attraper l'exception jusqu'à ce que vous atteigniez une certaine longueur. Plus la longueur est petite, plus vite c'est
Dans mes tests très peu scientifiques: pour 10000 itérations pour une longueur de caractères de 100 000 à 110000, il était 2,7 fois plus rapide de tester en premier.
Pour 1000 itérations pour des caractères de 1 à 16 caractères pour un total de 16 000 tests, c'était 10,9 fois plus rapide.
Je suis sûr qu'il y a un moment où il devient préférable de tester avec la méthode basée sur les exceptions. Je ne sais tout simplement pas à quel point c'est.
la source
=
signe. Si le remplissage est incorrect, cela donnera une erreur même si l'entrée correspond à une expression.\n\fLE16
- votre méthode donnerait un faux positif pour cela. Pour tous ceux qui lisent et recherchent une méthode infaillible; Je recommanderais d'attraper l'exception FormatException ou d'utiliser un RegEx adapté aux spécifications, voir stackoverflow.com/questions/475074/… .@"^[a-zA-Z0-9\+/]*={0,2}$"
Réponses:
Il est assez facile de reconnaître une chaîne Base64, car elle ne sera composée que de caractères
'A'..'Z', 'a'..'z', '0'..'9', '+', '/'
et elle est souvent complétée à la fin avec jusqu'à trois '=', pour faire de la longueur un multiple de 4. Mais au lieu de les comparer, vous ' Il vaut mieux ignorer l'exception, si elle se produit.la source
Utilisez Convert.TryFromBase64String à partir de C # 7.2
la source
Convert.TryFromBase64String(base64.PadRight(base64.Length / 4 * 4 + (base64.Length % 4 == 0 ? 0 : 4), '='), new Span<byte>(new byte[base64.Length]), out _)
. Je vous remercie.Je sais que vous avez dit que vous ne vouliez pas attraper une exception. Mais, parce qu'il est plus fiable d'attraper une exception, je vais publier cette réponse.
Mise à jour: j'ai mis à jour la condition grâce à oybek pour améliorer encore la fiabilité.
la source
base64String.Contains
plusieurs fois peut entraîner des performances médiocres dans le cas d'base64String
une grande chaîne.base64String== null || base64String.Length == 0
avecstring.IsNullOrEmpty(base64String)
Je pense que l'expression régulière devrait être:
Correspondant uniquement à un ou deux signes «=» de fin, pas trois.
s
devrait être la chaîne qui sera vérifiée.Regex
fait partie de l'System.Text.RegularExpressions
espace de noms.la source
Pourquoi ne pas simplement attraper l'exception et renvoyer False?
Cela évite une surcharge supplémentaire dans le cas courant.
la source
Par souci d'exhaustivité, je souhaite fournir une mise en œuvre. De manière générale, Regex est une approche coûteuse, surtout si la chaîne est volumineuse (ce qui se produit lors du transfert de fichiers volumineux). L'approche suivante essaie d'abord les moyens les plus rapides de détection.
ÉDITER
Comme suggéré par Sam , vous pouvez également modifier légèrement le code source. Il propose une approche plus performante pour la dernière étape des tests. La routine
peut être utilisé pour remplacer
if (!Base64Chars.Contains(value[i]))
ligne parif (IsInvalid(value[i]))
Le code source complet avec les améliorations de Sam ressemblera à ceci (commentaires supprimés pour plus de clarté)
la source
La réponse doit dépendre de l'utilisation de la chaîne. Il y a beaucoup de chaînes qui peuvent être "base64 valide" selon la syntaxe suggérée par plusieurs afficheurs, mais qui peuvent "correctement" décoder, sans exception, en junk. Exemple: la chaîne 8char
Portland
est valide en Base64. Quel est l'intérêt de dire qu'il s'agit de base64 valide? Je suppose qu'à un moment donné, vous voudrez savoir que cette chaîne devrait ou ne devrait pas être décodée en Base64.Dans mon cas, j'ai des chaînes de connexion Oracle qui peuvent être en texte brut comme:
ou en base64 comme
Je dois juste vérifier la présence d'un point-virgule, car cela prouve que ce n'est PAS base64, ce qui est bien sûr plus rapide que n'importe quelle méthode ci-dessus.
la source
Règles du football Knibb High!
Cela devrait être relativement rapide et précis, mais j'avoue que je ne l'ai pas soumis à un test approfondi, juste quelques-uns.
Il évite les exceptions coûteuses, regex, et évite également de parcourir un jeu de caractères, en utilisant à la place des plages ascii pour la validation.
la source
la source
J'utiliserai comme ça pour ne pas avoir besoin d'appeler à nouveau la méthode de conversion
la source
Décodez, réencodez et comparez le résultat à la chaîne d'origine
la source
Imho ce n'est pas vraiment possible. Toutes les solutions publiées échouent pour des chaînes telles que "test" et ainsi de suite. S'ils peuvent être divisés par 4, ne sont pas nuls ou vides, et s'ils sont un caractère base64 valide, ils réussiront tous les tests. Cela peut être plusieurs chaînes ...
Il n'y a donc pas de vraie solution autre que de savoir qu'il s'agit d'une chaîne encodée en base 64 . Voici ce que j'ai trouvé:
Je m'attends à ce que la chaîne décodée commence par une certaine structure, alors je vérifie cela.
la source
Sûr. Assurez - vous que chaque personnage est à l' intérieur
a-z
,A-Z
,0-9
,/
, ou+
, et les extrémités de chaîne avec==
. (Au moins, c'est l'implémentation Base64 la plus courante. Vous pouvez trouver des implémentations qui utilisent des caractères différents de/
ou+
pour les deux derniers caractères.)la source
Oui, puisque Base64 encode les données binaires en chaînes ASCII en utilisant un jeu limité de caractères, vous pouvez simplement le vérifier avec cette expression régulière:
/ ^ [A-Za-z0-9 \ = \ + \ / \ s \ n] + $ / s
ce qui garantira que la chaîne ne contient que AZ, az, 0-9, '+', '/', '=' et des espaces.
la source
=
caractère à la fin. Si ce remplissage n'est pas valide, ce n'est pas un encodage base64 correct, même s'il correspond à votre regex. Vous pouvez en faire la démonstration en trouvant une chaîne de base 64 avec 1 ou 2=
à la fin, en les supprimant et en essayant de la décoder.Je suggérerais de créer une regex pour faire le travail. Vous devrez vérifier quelque chose comme ceci: [a-zA-Z0-9 + / =] Vous devrez également vérifier la longueur de la chaîne. Je ne suis pas sûr sur celui-ci, mais je suis presque sûr que si quelque chose est coupé (autre que le rembourrage "="), il exploserait.
Ou mieux encore, consultez cette question stackoverflow
la source
Je viens d'avoir une exigence très similaire où je laisse l'utilisateur faire une manipulation d'image dans un
<canvas>
élément, puis envoyer l'image résultante récupérée avec.toDataURL()
au backend. Je voulais faire une validation du serveur avant d'enregistrer l'image et j'ai implémenté un enValidationAttribute
utilisant une partie du code d'autres réponses:Comme vous pouvez le voir, j'attends une chaîne de type image / png, qui est la valeur par défaut renvoyée par
<canvas>
lors de l'utilisation.toDataURL()
.la source
Vérifiez Base64 ou chaîne normale
public bool IsBase64Encoded (chaîne de caractères)
{
}
la source
Toutes les réponses ont été digérées dans 1 fonction qui garantit à 100% que ses résultats seront exacts.
1) Utilisez la fonction comme ci-dessous:
2) Voici la fonction:
la source
J'aime l'idée d'une vérification d'expression régulière. Les expressions régulières peuvent être rapides et économiser parfois la surcharge de codage. l'enquête originale, avait une mise à jour qui a fait exactement cela. Je trouve cependant que je ne peux jamais supposer que les chaînes ne seraient pas nulles. J'étendrais la fonction Extension pour vérifier la chaîne source pour les caractères nuls ou pour les espaces uniquement.
la source