Gibt es in C # eine andere Möglichkeit, festzustellen, ob eine Zeichenfolge Base 64-codiert ist, als nur zu versuchen, sie zu konvertieren, und festzustellen, ob ein Fehler vorliegt? Ich habe folgenden Codecode:
// Convert base64-encoded hash value into a byte array.
byte[] HashBytes = Convert.FromBase64String(Value);
Ich möchte die Ausnahme "Ungültiges Zeichen in einer Base-64-Zeichenfolge" vermeiden, die auftritt, wenn der Wert keine gültige Base-64-Zeichenfolge ist. Ich möchte nur false überprüfen und zurückgeben, anstatt eine Ausnahme zu behandeln, da ich davon ausgehe, dass dieser Wert manchmal keine Basis-64-Zeichenfolge ist. Gibt es eine Möglichkeit, dies zu überprüfen, bevor Sie die Convert.FromBase64String-Funktion verwenden?
Vielen Dank!
Update:
Danke für all deine Antworten. Hier ist eine Erweiterungsmethode, die Sie alle verwenden können. Sie scheint sicherzustellen, dass Ihre Zeichenfolge ausnahmslos Convert.FromBase64String besteht. .NET scheint beim Konvertieren in Basis 64 alle nachgestellten und endenden Leerzeichen zu ignorieren, sodass "1234" und "1234" gültig sind.
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);
}
Für diejenigen, die sich über die Leistung des Testens im Vergleich zu Fang und Ausnahme wundern, ist es in den meisten Fällen für diese Basis-64-Sache schneller zu überprüfen, als die Ausnahme zu fangen, bis Sie eine bestimmte Länge erreicht haben. Je kleiner die Länge, desto schneller
In meinen sehr unwissenschaftlichen Tests: Bei 10000 Iterationen für die Zeichenlänge 100.000 - 110000 war es 2,7-mal schneller, zuerst zu testen.
Bei 1000 Iterationen für Zeichen mit einer Länge von 1 bis 16 Zeichen für insgesamt 16.000 Tests war es 10,9-mal schneller.
Ich bin sicher, dass es einen Punkt gibt, an dem es besser wird, mit der ausnahmebasierten Methode zu testen. Ich weiß nur nicht, an welchem Punkt das ist.
quelle
=
Zeichen. Wenn das Auffüllen falsch ist, wird ein Fehler ausgegeben, obwohl die Eingabe mit einem Ausdruck übereinstimmt.\n\fLE16
- Ihre Methode würde hierfür ein falsches Positiv ergeben. Für alle, die eine narrensichere Methode lesen und suchen; Ich würde empfehlen, die FormatException abzufangen oder eine für die Spezifikation geeignete RegEx zu verwenden, siehe stackoverflow.com/questions/475074/… .@"^[a-zA-Z0-9\+/]*={0,2}$"
Antworten:
Es ist ziemlich einfach, eine Base64-Zeichenfolge zu erkennen, da sie nur aus Zeichen besteht
'A'..'Z', 'a'..'z', '0'..'9', '+', '/'
und am Ende häufig mit bis zu drei '=' aufgefüllt wird, um die Länge zu einem Vielfachen von 4 zu machen. Aber anstatt diese zu vergleichen, müssen Sie ' d ist besser dran, die Ausnahme zu ignorieren, wenn sie auftritt.quelle
Verwenden Sie Convert.TryFromBase64String aus C # 7.2
quelle
Convert.TryFromBase64String(base64.PadRight(base64.Length / 4 * 4 + (base64.Length % 4 == 0 ? 0 : 4), '='), new Span<byte>(new byte[base64.Length]), out _)
. Danke dir.Ich weiß, dass Sie gesagt haben, Sie wollten keine Ausnahme machen. Da das Abfangen einer Ausnahme zuverlässiger ist, werde ich diese Antwort veröffentlichen.
Update: Ich habe den Zustand dank oybek aktualisiert , um die Zuverlässigkeit weiter zu verbessern.
quelle
base64String.Contains
Mehrfaches Aufrufen kann zu einer schlechten Leistung führen, wennbase64String
es sich um eine große Zeichenfolge handelt.base64String== null || base64String.Length == 0
mitstring.IsNullOrEmpty(base64String)
Ich glaube, der reguläre Ausdruck sollte sein:
Nur ein oder zwei nachfolgende '=' Zeichen, nicht drei.
s
sollte die Zeichenfolge sein, die überprüft wird.Regex
ist Teil desSystem.Text.RegularExpressions
Namespace.quelle
Warum nicht einfach die Ausnahme abfangen und False zurückgeben?
Dies vermeidet im allgemeinen Fall zusätzlichen Aufwand.
quelle
Der Vollständigkeit halber möchte ich eine Implementierung bereitstellen. Im Allgemeinen ist Regex ein teurer Ansatz, insbesondere wenn die Zeichenfolge groß ist (was beim Übertragen großer Dateien der Fall ist). Der folgende Ansatz versucht zuerst die schnellsten Erkennungsmethoden.
BEARBEITEN
Wie von Sam vorgeschlagen , können Sie den Quellcode auch geringfügig ändern. Er bietet einen leistungsfähigeren Ansatz für den letzten Testschritt. Die Routine
kann verwendet werden, um die
if (!Base64Chars.Contains(value[i]))
Linie durch zu ersetzenif (IsInvalid(value[i]))
Der vollständige Quellcode mit Verbesserungen von Sam sieht folgendermaßen aus (Kommentare wurden aus Gründen der Übersichtlichkeit entfernt).
quelle
Die Antwort muss von der Verwendung der Zeichenfolge abhängen. Es gibt viele Zeichenfolgen, die gemäß der von mehreren Postern vorgeschlagenen Syntax "valid base64" sein können, die jedoch ausnahmslos "korrekt" in Junk dekodieren können. Beispiel: Die 8-Zeichen-Zeichenfolge
Portland
ist gültig Base64. Was ist der Grund dafür, dass dies eine gültige Base64 ist? Ich denke, irgendwann möchten Sie wissen, dass diese Zeichenfolge Base64-decodiert sein sollte oder nicht.In meinem Fall habe ich Oracle-Verbindungszeichenfolgen, die möglicherweise im Klartext vorliegen:
oder in base64 wie
Ich muss nur nach einem Semikolon suchen, da dies beweist, dass es sich NICHT um base64 handelt, was natürlich schneller ist als jede der oben genannten Methoden.
quelle
Knibb Hohe Fußballregeln!
Dies sollte relativ schnell und genau sein, aber ich gebe zu, dass ich es nicht gründlich getestet habe, nur ein paar.
Es vermeidet teure Ausnahmen, Regex und das Durchlaufen eines Zeichensatzes, stattdessen werden ASCII-Bereiche zur Validierung verwendet.
quelle
quelle
Ich werde dies verwenden, damit ich die Konvertierungsmethode nicht erneut aufrufen muss
quelle
Dekodieren Sie das Ergebnis, codieren Sie es neu und vergleichen Sie es mit der ursprünglichen Zeichenfolge
quelle
Imho ist das nicht wirklich möglich. Alle veröffentlichten Lösungen schlagen für Zeichenfolgen wie "Test" usw. fehl . Wenn sie durch 4 geteilt werden können, nicht null oder leer sind und wenn sie ein gültiges base64-Zeichen sind, bestehen sie alle Tests. Das können viele Saiten sein ...
Es gibt also keine wirkliche Lösung, außer zu wissen, dass dies eine Base 64-codierte Zeichenfolge ist . Was ich mir ausgedacht habe, ist Folgendes:
Ich erwarte, dass der dekodierte String mit einer bestimmten Struktur beginnt, also überprüfe ich das.
quelle
Sicher. So stellen Sie sicher , dass jedes Zeichen in
a-z
,A-Z
,0-9
,/
, oder+
, und die Schnurenden mit==
. (Zumindest ist das die häufigste Base64 - Implementierung. Sie könnten einige Implementierungen , dass die Verwendung Zeichen anders finden/
oder+
für die letzten zwei Zeichen ein .)quelle
Ja, da Base64 Binärdaten mit einem begrenzten Zeichensatz in ASCII-Zeichenfolgen codiert, können Sie dies einfach mit diesem regulären Ausdruck überprüfen:
/ ^ [A-Za-z0-9 \ = \ + \ / \ s \ n] + $ / s
Dadurch wird sichergestellt, dass die Zeichenfolge nur AZ, az, 0-9, '+', '/', '=' und Leerzeichen enthält.
quelle
=
Zeichen am Ende mit dem Zeichen am Ende auf. Wenn diese Auffüllung ungültig ist, handelt es sich nicht um eine korrekte Base64-Codierung, obwohl sie mit Ihrer Regex übereinstimmt. Sie können dies demonstrieren=
, indem Sie eine 64-Zeichenfolge mit 1 oder 2 am Ende suchen , diese entfernen und versuchen, sie zu dekodieren.Ich würde vorschlagen, einen regulären Ausdruck zu erstellen, um die Arbeit zu erledigen. Sie müssen Folgendes überprüfen: [a-zA-Z0-9 + / =] Sie müssen auch die Länge der Zeichenfolge überprüfen. Ich bin mir nicht sicher, aber ich bin mir ziemlich sicher, dass etwas, das beschnitten wird (außer der Polsterung "="), explodieren würde.
Oder besser noch diese Frage zum Stapelüberlauf
quelle
Ich hatte gerade eine sehr ähnliche Anforderung, bei der ich den Benutzer einige Bildmanipulationen in einem
<canvas>
Element durchführen und dann das resultierende Bild, das mit abgerufen wurde,.toDataURL()
an das Backend senden kann . Ich wollte vor dem Speichern des Images eine Serverüberprüfung durchführen und habe einenValidationAttribute
Teil des Codes aus anderen Antworten implementiert :Wie Sie sehen können, erwarte ich eine Zeichenfolge vom Typ image / png. Dies ist die Standardeinstellung, die
<canvas>
bei der Verwendung zurückgegeben wird.toDataURL()
.quelle
Überprüfen Sie Base64 oder eine normale Zeichenfolge
public bool IsBase64Encoded (String str)
{
}}
quelle
Alle Antworten wurden in eine Funktion zusammengefasst, die zu 100% sicherstellt, dass die Ergebnisse korrekt sind.
1) Verwenden Sie die folgende Funktion:
2) Unten ist die Funktion:
quelle
Ich mag die Idee einer Prüfung auf reguläre Ausdrücke. Reguläre Ausdrücke können schnell sein und zeitweise den Codierungsaufwand sparen. Die ursprüngliche Anfrage hatte ein Update, das genau dies tat. Ich finde jedoch, dass ich niemals davon ausgehen kann, dass die Zeichenfolgen nicht null sind. Ich würde die Erweiterungsfunktion erweitern, um die Quellzeichenfolge auf Null- oder Nur-Leerzeichen-Zeichen zu überprüfen.
quelle