So überprüfen Sie, ob eine Zeichenfolge Base64-codiert ist oder nicht
194
Ich möchte eine Base64-codierte Zeichenfolge dekodieren und dann in meiner Datenbank speichern. Wenn die Eingabe nicht Base64-codiert ist, muss ich einen Fehler auslösen.
Wie kann ich überprüfen, ob eine Zeichenfolge Base64-codiert ist?
Ohne anzugeben, auf welche Programmiersprache (und / oder welches Betriebssystem) Sie abzielen, ist dies eine sehr offene Frage
bcarroll
5
Sie können lediglich feststellen, dass die Zeichenfolge nur Zeichen enthält, die für eine Base64-codierte Zeichenfolge gültig sind. Es ist möglicherweise nicht möglich festzustellen, dass die Zeichenfolge die Base64-codierte Version einiger Daten ist. Beispiel test1234: Eine gültige Base64-codierte Zeichenfolge. Wenn Sie sie dekodieren, erhalten Sie einige Bytes. Es gibt keine anwendungsunabhängige Schlussfolgerung, dass test1234es sich nicht um eine Base64-codierte Zeichenfolge handelt.
Bei der Base64-Codierung lautet der Zeichensatz [A-Z, a-z, 0-9, and + /]. Wenn die Restlänge weniger als 4 beträgt, wird die Zeichenfolge mit '='Zeichen aufgefüllt .
^([A-Za-z0-9+/]{4})* bedeutet, dass die Zeichenfolge mit 0 oder mehr base64-Gruppen beginnt.
([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$bedeutet , dass die Schnurenden in einer von drei Formen: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=oder [A-Za-z0-9+/]{2}==.
Ich wollte nur überprüfen, bitte helfen Sie bei meiner Frage: Was ist die Garantie, dass sich dieser reguläre Ausdruck immer nur auf den Base64-String bezieht? Wenn eine Zeichenfolge kein Leerzeichen enthält und ein Vielfaches von 4 Zeichen ist, wird diese Zeichenfolge als base64-Zeichenfolge betrachtet.
DShah
3
Dann ist es eine gültige base64-Zeichenfolge, die dekodiert werden kann. Sie können eine Mindestlängenbeschränkung hinzufügen. Anstelle von null oder mehr Wiederholungen von Vierergruppen sind beispielsweise vier oder mehr erforderlich. Es hängt auch von Ihrem Problem ab; Wenn Ihre Benutzer häufig ein einzelnes Wort in einer Sprache mit langen Wörtern und reinem ASCII (Hawaiianisch?) eingeben, ist dies fehleranfälliger als wenn Eingaben ohne Base64 normalerweise Leerzeichen, Interpunktion usw. enthalten
Tripleee
62
Das sagt nur , dass ein Eingang gewesen sein könnte ein b64 codierten Wert, aber nicht sagen , ob der Eingang ist eigentlich ein b64 codierte Wert. Mit anderen Worten, abcdwird übereinstimmen, aber es ist nicht unbedingt der codierte Wert i·einer einfachen abcdEingabe
Tzury Bar Yochay
3
Ihr regulärer Ausdruck ist falsch, da er nicht mit der leeren Zeichenfolge übereinstimmt. Dies ist die base64-Codierung von Binärdaten mit der Länge Null gemäß RFC 4648.
rötlich
5
@Adomas, "pass" ist ein perfekt gültige Base64 string, daß Decodierungen in die Sequenz von Bytes 0xa5, 0xabund 0x2c. Warum sollten Sie es a priori verwerfen , wenn Sie nicht mehr Kontext zur Entscheidung haben?
Luis Colorado
50
Wenn Sie Java verwenden, können Sie tatsächlich die Commons-Codec- Bibliothek verwenden
aus der Dokumentation: isArrayByteBase64(byte[] arrayOctet)Veraltet. 1.5 Verwendung isBase64(byte[])wird in 2.0 entfernt.
Avinash R
7
Sie können auch Base64.isBase64 (String base64) verwenden, anstatt es selbst in ein Byte-Array zu konvertieren.
Sasa
5
Basierend auf der Dokumentation: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : " Testet einen bestimmten String, um festzustellen , ob er nur gültige Zeichen im Base64-Alphabet enthält. Derzeit behandelt die Methode Leerzeichen als gültig." Dies bedeutet, dass diese Methode einige falsch positive Ergebnisse wie "Leerzeichen" oder Zahlen ("0", "1") aufweist.
Christian Vielma
für Zeichenfolge Base64.isBase64 (Inhalt)
ema
3
Diese Antwort ist falsch, da sie stringToBeChecked="some plain text"dann festgelegt wird boolean isBase64=true, obwohl es sich nicht um einen Base64-codierten Wert handelt. Lesen Sie die Quelle für Commons-Codec-1.4. Base64.isArrayByteBase64()Sie prüft nur, ob jedes Zeichen in der Zeichenfolge gültig ist, um für die Base64-Codierung berücksichtigt zu werden, und lässt Leerzeichen zu.
Brad
49
Ja, du kannst:
Überprüfen Sie, ob die Länge ein Vielfaches von 4 Zeichen ist
Überprüfen Sie, ob sich jedes Zeichen in der Menge AZ, az, 0-9, +, / befindet, mit Ausnahme des Auffüllens am Ende, das aus 0, 1 oder 2 '=' Zeichen besteht
Wenn Sie erwarten, dass es sich um base64 handelt, können Sie wahrscheinlich einfach die auf Ihrer Plattform verfügbare Bibliothek verwenden, um zu versuchen , sie in ein Byte-Array zu dekodieren. Wenn dies keine gültige Base 64 ist, wird eine Ausnahme ausgelöst. Dies hängt von Ihrer Plattform ab. natürlich.
Das Parsen unterscheidet sich von der Validierung zumindest dadurch, dass für das decodierte Byte-Array Speicher erforderlich ist. Dies ist in einigen Fällen nicht der effektivste Ansatz.
Victor Yarema
1
@ VictorYarema: Ich habe sowohl einen Nur-Validierungs-Ansatz (Aufzählungspunkte) als auch einen Parsing-Ansatz (nach den Aufzählungspunkten) vorgeschlagen.
Jon Skeet
16
Ab Java 8 können Sie einfach java.util.Base64 verwenden , um zu versuchen, die Zeichenfolge zu dekodieren:
Ja, es ist eine Option, aber vergessen Sie nicht, dass der Fang in Java ziemlich teuer ist
Panser
2
Das ist nicht mehr der Fall. Die Ausnahmebehandlung funktioniert ziemlich gut. Sie sollten besser nicht vergessen, dass Java Regex ziemlich langsam ist. Ich meine: WIRKLICH LANGSAM! Es ist tatsächlich schneller, einen Base64 zu dekodieren und zu überprüfen, ob er (nicht) funktioniert, anstatt den String mit dem obigen Regex abzugleichen. Ich habe einen groben Test durchgeführt und der Java Regex-Abgleich ist ungefähr sechsmal langsamer (!!) als das Abfangen einer eventuellen Ausnahme bei der Dekodierung.
Sven Döring
Mit mehr Testläufen ist es tatsächlich elfmal langsamer. Es ist Zeit für eine bessere Regex-Implementierung in Java. Sogar eine Regex-Prüfung mit der Nashorn JavaScript-Engine in Java ist so viel schneller. Unglaublich. Zusätzlich ist JavaScript Regex (mit Nashorn) viel leistungsfähiger.
Sven Döring
3
Mit Java 11 (anstelle von Java 8) ist die Regex-Prüfung sogar 22-mal langsamer. 🤦 (Weil die Base64-Dekodierung schneller wurde.)
Sven Döring
15
Versuchen Sie dies für PHP5
//where $json is some data that can be base64 encoded
$json=some_data;
//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{
echo "base64 encoded";
}
else
{
echo "not base64 encoded";
}
Verwenden Sie dies für PHP7
//$string parameter can be base64 encoded or not
function is_base64_encoded($string){
//this will check if $string is base64 encoded and return true, if it is.
if (base64_decode($string, true) !== false){
return true;
}else{
return false;
}
}
Welche Sprache ist das? Die Frage wurde gestellt, ohne sich auf eine Sprache zu beziehen
Ozkan
das wird nicht funktionieren. Lesen Sie die Dokumente Returns FALSE if input contains character from outside the base64 alphabet.base64_decode
Aley
1
Wie? Wenn die Eingabe ein externes Zeichen enthält, ist es nicht base64, oder?
Suneel Kumar
6
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string
if (isBase64Valid) {
// true if base64 formate
console.log('It is base64');
} else {
// false if not in base64 formate
console.log('it is not in base64');
}
Überprüfen Sie , WENN die Länge der Zeichenfolge ist ein Vielfaches von 4 Aftwerwards verwenden diese Regex um sicherzustellen , dass alle Zeichen in der Zeichenfolge sind Base64 - Zeichen.
\A[a-zA-Z\d\/+]+={,2}\z
Wenn die von Ihnen verwendete Bibliothek eine neue Zeile hinzufügt, um die Regel mit maximal 76 Zeichen pro Zeile zu beachten, ersetzen Sie sie durch leere Zeichenfolgen.
Der erwähnte Link zeigt 404. Bitte überprüfen und aktualisieren.
Ankur
Sorry @AnkurKumar, aber genau das passiert, wenn Leute uncoole URLs haben: Sie ändern sich ständig. Ich habe keine Ahnung, wohin es gezogen ist. Ich hoffe, Sie finden andere nützliche Ressourcen über Google
Es gibt viele Varianten von Base64. Stellen Sie also fest, ob Ihre Zeichenfolge der erwarteten Variablen ähnelt . Als solche müssen Sie die Regex unten in Bezug auf den Index und Füllzeichen einzustellen (dh +, /, =).
class String
def resembles_base64?
self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
end
end
Verwendung:
raise 'the string does not resemble Base64' unless my_string.resembles_base64?
Es ist unmöglich zu überprüfen, ob eine Zeichenfolge base64-codiert ist oder nicht. Es ist nur möglich zu überprüfen, ob diese Zeichenfolge ein Base64-codiertes Zeichenfolgenformat hat. Dies würde bedeuten, dass es sich um eine Zeichenfolge handelt, die durch Base64-Codierung erzeugt wird (um zu überprüfen, ob die Zeichenfolge gegen einen regulären Ausdruck validiert werden kann oder eine Bibliothek verwendet werden kann, können viele verwendet werden Andere Antworten auf diese Frage bieten gute Möglichkeiten, dies zu überprüfen, sodass ich nicht auf Details eingehen werde.
Beispielsweise ist string floweine gültige base64-codierte Zeichenfolge. Es ist jedoch unmöglich zu wissen, ob es sich nur um eine einfache Zeichenfolge, ein englisches Wort flowoder um eine Basis-64-codierte Zeichenfolge handelt~Z0
Dieser reguläre Ausdruck hat mir geholfen, die base64 in meiner Anwendung in Rails zu identifizieren. Ich hatte nur ein Problem: Er erkennt die Zeichenfolge "errorDescripcion". Ich generiere einen Fehler, um sie zu lösen. Überprüfen Sie einfach die Länge einer Zeichenfolge.
Der obige reguläre Ausdruck /^.....$/.match(my_string) gibt einen Formatierungsfehler aus, indem er "
Nicht übereinstimmendes
Und mit 'vorzeitigem Ende der Zeichenklasse: / ^ (([A-Za-z0-9 + /' Syntaxfehler.
james2611nov
Nevermind hat das Problem behoben, indem \ vor jedem / Zeichen \ hinzugefügt wurde.
James2611nov
errorDescriptionist eine gültige base64-Zeichenfolge, die in die binäre Folge von Bytes (in hex) dekodiert : 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
Luis Colorado
Es hat perfekt funktioniert, um die Base64-codierte Zeichenfolge zu überprüfen.
Deepak Lakhara
1
Dies funktioniert in Python:
import base64
def IsBase64(str):
try:
base64.b64decode(str)
return True
except Exception as e:
return False
if IsBase64("ABC"):
print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
print("ABC is NOT Base64-encoded.")
if IsBase64("QUJD"):
print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
print("QUJD is NOT Base64-encoded.")
Zusammenfassung:IsBase64("string here") Gibt true zurück , wenn string hereBase64-codiert ist, und false, wenn string hereNICHT Base64-codiert ist.
Die Empfehlung, die Programmiersprache zu wechseln, um ein Problem zu lösen, ist im Allgemeinen keine gültige Antwort.
Luis Colorado
0
Es gibt keine Möglichkeit, Zeichenfolge und Base64-Codierung zu unterscheiden, es sei denn, die Zeichenfolge in Ihrem System weist eine bestimmte Einschränkung oder Identifikation auf.
Dieses Snippet kann nützlich sein, wenn Sie die Länge des ursprünglichen Inhalts kennen (z. B. eine Prüfsumme). Es wird überprüft, ob das codierte Formular die richtige Länge hat.
public static boolean isValidBase64( final int initialLength, final String string ) {
final int padding ;
final String regexEnd ;
switch( ( initialLength ) % 3 ) {
case 1 :
padding = 2 ;
regexEnd = "==" ;
break ;
case 2 :
padding = 1 ;
regexEnd = "=" ;
break ;
default :
padding = 0 ;
regexEnd = "" ;
}
final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
return Pattern.compile( regex ).matcher( string ).matches() ;
}
Wenn die RegEx nicht funktioniert und Sie den Formatstil der ursprünglichen Zeichenfolge kennen, können Sie die Logik umkehren, indem Sie für dieses Format eine Regexing durchführen.
Zum Beispiel arbeite ich mit Base64-codierten XML-Dateien und überprüfe nur, ob die Datei ein gültiges XML-Markup enthält. Wenn nicht, kann ich davon ausgehen, dass es base64 dekodiert ist. Dies ist nicht sehr dynamisch, funktioniert aber gut für meine kleine Anwendung.
Versuchen Sie dies mit einem zuvor erwähnten regulären Ausdruck:
String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
System.out.println("it's a Base64");
}
... Wir können auch eine einfache Validierung durchführen, z. B. wenn Leerzeichen vorhanden sind, kann es sich nicht um Base64 handeln:
String myString = "Hello World";
if(myString.contains(" ")){
System.out.println("Not B64");
}else{
System.out.println("Could be B64 encoded, since it has no spaces");
}
Wenn beim Dekodieren eine Zeichenfolge mit ASCII-Zeichen angezeigt wird, wurde die Zeichenfolge nicht codiert
(RoR) Rubinlösung:
def encoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end
def decoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end
test1234
: Eine gültige Base64-codierte Zeichenfolge. Wenn Sie sie dekodieren, erhalten Sie einige Bytes. Es gibt keine anwendungsunabhängige Schlussfolgerung, dasstest1234
es sich nicht um eine Base64-codierte Zeichenfolge handelt.Antworten:
Mit dem folgenden regulären Ausdruck können Sie überprüfen, ob eine Zeichenfolge base64-codiert ist oder nicht:
Bei der Base64-Codierung lautet der Zeichensatz
[A-Z, a-z, 0-9, and + /]
. Wenn die Restlänge weniger als 4 beträgt, wird die Zeichenfolge mit'='
Zeichen aufgefüllt .^([A-Za-z0-9+/]{4})*
bedeutet, dass die Zeichenfolge mit 0 oder mehr base64-Gruppen beginnt.([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$
bedeutet , dass die Schnurenden in einer von drei Formen:[A-Za-z0-9+/]{4}
,[A-Za-z0-9+/]{3}=
oder[A-Za-z0-9+/]{2}==
.quelle
abcd
wird übereinstimmen, aber es ist nicht unbedingt der codierte Werti·
einer einfachenabcd
Eingabe"pass"
ist ein perfekt gültige Base64 string, daß Decodierungen in die Sequenz von Bytes0xa5
,0xab
und0x2c
. Warum sollten Sie es a priori verwerfen , wenn Sie nicht mehr Kontext zur Entscheidung haben?Wenn Sie Java verwenden, können Sie tatsächlich die Commons-Codec- Bibliothek verwenden
quelle
isArrayByteBase64(byte[] arrayOctet)
Veraltet. 1.5 VerwendungisBase64(byte[])
wird in 2.0 entfernt.stringToBeChecked="some plain text"
dann festgelegt wirdboolean isBase64=true
, obwohl es sich nicht um einen Base64-codierten Wert handelt. Lesen Sie die Quelle für Commons-Codec-1.4.Base64.isArrayByteBase64()
Sie prüft nur, ob jedes Zeichen in der Zeichenfolge gültig ist, um für die Base64-Codierung berücksichtigt zu werden, und lässt Leerzeichen zu.Ja, du kannst:
Wenn Sie erwarten, dass es sich um base64 handelt, können Sie wahrscheinlich einfach die auf Ihrer Plattform verfügbare Bibliothek verwenden, um zu versuchen , sie in ein Byte-Array zu dekodieren. Wenn dies keine gültige Base 64 ist, wird eine Ausnahme ausgelöst. Dies hängt von Ihrer Plattform ab. natürlich.
quelle
Ab Java 8 können Sie einfach java.util.Base64 verwenden , um zu versuchen, die Zeichenfolge zu dekodieren:
quelle
Versuchen Sie dies für PHP5
Verwenden Sie dies für PHP7
quelle
Returns FALSE if input contains character from outside the base64 alphabet.
base64_decodequelle
Überprüfen Sie , WENN die Länge der Zeichenfolge ist ein Vielfaches von 4 Aftwerwards verwenden diese Regex um sicherzustellen , dass alle Zeichen in der Zeichenfolge sind Base64 - Zeichen.
\A[a-zA-Z\d\/+]+={,2}\z
Wenn die von Ihnen verwendete Bibliothek eine neue Zeile hinzufügt, um die Regel mit maximal 76 Zeichen pro Zeile zu beachten, ersetzen Sie sie durch leere Zeichenfolgen.
quelle
Es gibt viele Varianten von Base64. Stellen Sie also fest, ob Ihre Zeichenfolge der erwarteten Variablen ähnelt . Als solche müssen Sie die Regex unten in Bezug auf den Index und Füllzeichen einzustellen (dh
+
,/
,=
).Verwendung:
quelle
Versuche dies:
quelle
Es ist unmöglich zu überprüfen, ob eine Zeichenfolge base64-codiert ist oder nicht. Es ist nur möglich zu überprüfen, ob diese Zeichenfolge ein Base64-codiertes Zeichenfolgenformat hat. Dies würde bedeuten, dass es sich um eine Zeichenfolge handelt, die durch Base64-Codierung erzeugt wird (um zu überprüfen, ob die Zeichenfolge gegen einen regulären Ausdruck validiert werden kann oder eine Bibliothek verwendet werden kann, können viele verwendet werden Andere Antworten auf diese Frage bieten gute Möglichkeiten, dies zu überprüfen, sodass ich nicht auf Details eingehen werde.
Beispielsweise ist string
flow
eine gültige base64-codierte Zeichenfolge. Es ist jedoch unmöglich zu wissen, ob es sich nur um eine einfache Zeichenfolge, ein englisches Wortflow
oder um eine Basis-64-codierte Zeichenfolge handelt~Z0
quelle
Dieser reguläre Ausdruck hat mir geholfen, die base64 in meiner Anwendung in Rails zu identifizieren. Ich hatte nur ein Problem: Er erkennt die Zeichenfolge "errorDescripcion". Ich generiere einen Fehler, um sie zu lösen. Überprüfen Sie einfach die Länge einer Zeichenfolge.
quelle
errorDescription
ist eine gültige base64-Zeichenfolge, die in die binäre Folge von Bytes (in hex) dekodiert :7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27
.Dies funktioniert in Python:
Zusammenfassung:
IsBase64("string here")
Gibt true zurück , wennstring here
Base64-codiert ist, und false, wennstring here
NICHT Base64-codiert ist.quelle
C # Das ist großartig:
quelle
Console.WriteLine("test".IsBase64()); // true
Es gibt keine Möglichkeit, Zeichenfolge und Base64-Codierung zu unterscheiden, es sei denn, die Zeichenfolge in Ihrem System weist eine bestimmte Einschränkung oder Identifikation auf.
quelle
Dieses Snippet kann nützlich sein, wenn Sie die Länge des ursprünglichen Inhalts kennen (z. B. eine Prüfsumme). Es wird überprüft, ob das codierte Formular die richtige Länge hat.
quelle
Wenn die RegEx nicht funktioniert und Sie den Formatstil der ursprünglichen Zeichenfolge kennen, können Sie die Logik umkehren, indem Sie für dieses Format eine Regexing durchführen.
Zum Beispiel arbeite ich mit Base64-codierten XML-Dateien und überprüfe nur, ob die Datei ein gültiges XML-Markup enthält. Wenn nicht, kann ich davon ausgehen, dass es base64 dekodiert ist. Dies ist nicht sehr dynamisch, funktioniert aber gut für meine kleine Anwendung.
quelle
Dies funktioniert in Python:
quelle
Versuchen Sie dies mit einem zuvor erwähnten regulären Ausdruck:
... Wir können auch eine einfache Validierung durchführen, z. B. wenn Leerzeichen vorhanden sind, kann es sich nicht um Base64 handeln:
quelle
(RoR) Rubinlösung:
quelle
Ich versuche das zu benutzen, ja das hier funktioniert
aber ich habe die Bedingung hinzugefügt, um zu überprüfen, ob mindestens das Ende des Zeichens = ist
quelle
=
: Welche Spezifikation verwendenBase64
Sie? Wasend of the character
bedeutet und wielastIndexOf()
überprüft das nicht negativ ?