Nein, es ist nicht - die verknüpfte Frage ist neuer. Die verknüpfte Frage wird also zu einem Duplikat dieser Frage ...
Serge
Antworten:
206
Nein, Sie müssten es url-codieren, da base64-Zeichenfolgen die Zeichen "+", "=" und "/" enthalten können, die die Bedeutung Ihrer Daten ändern können - sehen Sie aus wie ein Unterordner.
URL-Codierung ist Platzverschwendung, zumal base64 selbst viele Zeichen unbenutzt lässt.
Michał Górny
21
Ich bin nicht sicher, ob ich verstehe, was Sie sagen - die URL-Codierung ändert keines der Zeichen außer den letzten drei Zeichen in der obigen Liste, und dies soll verhindern, dass sie falsch interpretiert werden, da sie in URLs andere Bedeutungen haben. Das gleiche gilt für base64, die Originaldaten können binär oder so sein, aber sie sind in einer Form codiert, die mit einfachen Protokollen einfach übertragen werden kann.
Thiyagaraj
3
Erstens sollten Sie auch '+' entkommen, da es in Raum umgewandelt werden kann. Zweitens gibt es mindestens wenige Zeichen, die für die Verwendung in URLs sicher sind und nicht im Standardzeichensatz verwendet werden. Ihre Methode kann in bestimmten Situationen sogar die Größe der übertragenen Daten dreimal erhöhen . Wenn Sie diese Zeichen durch andere ersetzen, wird der Trick ausgeführt, während die gleiche Länge beibehalten wird. Und es ist auch eine Standardlösung.
Aufgrund dieser Antwort diagnostizierte ich mein Problem als genau das, was es erwähnte. Einige der 64 Basiszeichen (+, /, =) wurden aufgrund der URL-Verarbeitung geändert. Als ich die Basis-64-Zeichenfolge per URL codierte, wurde das Problem behoben.
Chuck Krutsinger
272
Es gibt zusätzliche base64-Spezifikationen. (Einzelheiten finden Sie in der Tabelle hier ). Im Wesentlichen benötigen Sie jedoch 65 Zeichen zum Codieren: 26 Kleinbuchstaben + 26 Großbuchstaben + 10 Ziffern = 62.
Sie benötigen zwei weitere ['+', '/'] und ein Füllzeichen '='. Aber keiner von ihnen ist url-freundlich, also benutze einfach verschiedene Zeichen für sie und du bist fertig. Die Standardzeichen aus der obigen Tabelle sind ['-', '_'], aber Sie können andere Zeichen verwenden, solange Sie sie gleich dekodiert haben und nicht mit anderen teilen müssen.
function base64_url_encode($input){return strtr(base64_encode($input),'+/=','._-');}function base64_url_decode($input){return base64_decode(strtr($input,'._-','+/='));}
Tolle Lösung, außer dass Komma in URLs nicht uneingeschränkt bleibt. Ich empfehle '~' (Tilde) oder '.' (Punkt) stattdessen.
Kralyk
11
@kralyk: Ich empfehle nur, urlencodewie in Rodrigo-Silveiras Antwort vorgeschlagen. Wenn Sie zwei neue Funktionen erstellen, um wenige Zeichen in der URL-Länge zu sparen, betreten Sie Ihr Haus durch das Fenster, anstatt nur die Tür zu benutzen.
Marco Demaio
5
@MarcoDemaio, ohne zu wissen, wie es verwendet wird, ist es unmöglich zu sagen, dass es nur ein paar Zeichen sind. Jedes codierte Zeichen hat die dreifache Länge, und warum sollte "+++ ..." keine gültige base64-Zeichenfolge sein? URLs haben Browser-Limits. Wenn Sie eine URL verdreifachen, können Sie diese Limits erreichen.
Leewz
10
@RandalSchwartz Tilde ist URL-sicher. Von RFC3986:unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
@joeshmo Oder anstatt eine Hilfsfunktion zu schreiben, können Sie einfach die base64-codierte Zeichenfolge urlencodieren. Dies würde genau das Gleiche tun wie Ihre Hilfsfunktion, jedoch ohne die Notwendigkeit von zwei zusätzlichen Funktionen.
Das Ergebnis ist nicht genau das gleiche. urlencode verwendet 3 Zeichen, um ungültige Zeichen zu codieren, und joeshmos Lösung verwendet 1. Es ist kein großer Unterschied, aber es ist immer noch eine Verschwendung.
Josef Borkovec
1
@ JosefBorkovec Wirklich? Dann würde dies auch bedeuten, dass die gleiche Anzahl von Bytes, die base64-> url-> codiert ist, eine Vielzahl unterschiedlicher resultierender Längen sein könnte, während die andere Lösung eine vorhersagbare Länge ergibt, oder?
Menschlichkeit und
@humanityANDpeace Ja, Urlencode ist eine beschissene Lösung, weil es die Größe bestimmter base64-Strings verdreifacht. Sie können den Puffer auch nicht wiederverwenden, da die Ausgabe größer als die Eingabe ist.
Navin
4
Die Erweiterung von 1 auf 3 Zeichen erfolgt bei durchschnittlich 3 von 64 Zeichen, sodass ein Overhead von 9% (2 *
3/64
Seien Sie vorsichtig mit /Zeichen, wenn Sie es nicht als GET-Parameter, sondern als Pfad in der URL übergeben. Es wird Ihren Weg ändern, wenn Sie nicht /auf beiden Seiten durch etwas anderes ersetzen .
NeverEndingQueue
41
Einleitende Anmerkung Ich bin geneigt, einige Erläuterungen zu veröffentlichen, da einige der Antworten hier etwas irreführend waren (wenn nicht falsch).
Die Antwort lautet NEIN . Sie können nicht einfach einen Base64-codierten Parameter innerhalb einer URL-Abfragezeichenfolge übergeben, da Pluszeichen in ein Leerzeichen innerhalb des globalen Arrays $ _GET konvertiert werden. Mit anderen Worten, wenn Sie test.php gesendet haben? MyVar = stringwith + sign to
//test.phpprint $_GET['myVar'];
das Ergebnis wäre: stringwith sign
Die einfache Möglichkeit, dies zu lösen, besteht darin, einfach urlencode()Ihre base64-Zeichenfolge zu erstellen, bevor Sie sie zur Abfragezeichenfolge hinzufügen, um die Zeichen +, = und / in% ## -Codes zu maskieren. Gibt zum Beispiel urlencode("stringwith+sign")zurückstringwith%2Bsign
Wenn Sie die Aktion verarbeiten, übernimmt PHP die automatische Dekodierung der Abfragezeichenfolge, wenn das globale $ _GET gefüllt wird. Zum Beispiel, wenn ich test.php? MyVar = stringwith% 2Bsign an gesendet habe
//test.phpprint $_GET['myVar'];
das Ergebnis wäre: stringwith+sign
Sie nicht wollen, urldecode()die $ _GET String als + 's zurückgegeben werden in Leerzeichen umgewandelt werden.
Mit anderen Worten, wenn ich dieselbe test.php gesendet habe? MyVar = stringwith% 2Bsign to
Gute Antwort. Sie können PHP-Code ohne die Start- und End-Tags auf dieser Site verwenden, wenn die Frage mit PHP markiert ist (auch meistens ist dies aus dem Kontext der Frage ersichtlich). Wenn Sie am Ende einer Zeile zwei Leerzeichen einfügen, wird das angezeigt <br>, sodass Sie nicht viel HTML eingeben müssen. Ich hoffe das hilft, ich habe deine Antwort ein wenig bearbeitet, um sie noch weiter zu verbessern.
hakre
Vielen Dank für die Erwähnung, dass PHP die URL für Sie dekodiert. Das erspart mir, in ein Kaninchenloch zu fallen.
Cocest
Gute Antwort -> Sie möchten den zurückgegebenen $ _GET-String nicht urldecode (), da + in Leerzeichen konvertiert wird. Es wäre jedoch sicher, die Eingabe mit rawurldecode () zu versehen
MarcoZen
14
Ja und nein.
Der Basiszeichensatz von base64 kann in einigen Fällen mit herkömmlichen Konventionen kollidieren, die in URLs verwendet werden. Bei vielen Base64-Implementierungen können Sie den Zeichensatz jedoch so ändern, dass er besser mit URLs übereinstimmt, oder sogar mit einer (wie Pythons urlsafe_b64encode()).
Ein weiteres Problem, mit dem Sie möglicherweise konfrontiert sind, ist die Begrenzung der URL-Länge bzw. das Fehlen einer solchen Begrenzung. Da Standards keine maximale Länge festlegen, können Browser, Server, Bibliotheken und andere Software, die mit dem HTTP-Protokoll arbeiten, ihre eigenen Grenzen definieren. Sie können sich diesen Artikel ansehen: WWW-FAQs: Was ist die maximale Länge einer URL?
Dies funktioniert für Daten, die mit Java codiert sindBase64.getUrlEncoder().withoutPadding().encodeToString()
4
Ich denke nicht, dass dies sicher ist, da z. B. das Zeichen "=" in der Rohdatenbasis 64 verwendet wird und auch zur Unterscheidung der Parameter von den Werten in einem HTTP-GET verwendet wird.
Theoretisch ja, solange Sie die maximale Länge der URL und / oder der Abfragezeichenfolge für den Client oder Server nicht überschreiten.
In der Praxis kann es etwas schwieriger werden. Beispielsweise kann es eine HttpRequestValidationException in ASP.NET auslösen, wenn der Wert zufällig ein "Ein" enthält und Sie das nachfolgende "==" belassen.
Ja, es ist immer sicher. Natürlich enthält base64:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
aber eine base64-codierte Zeichenfolge hat normalerweise keine +. +wird in ein Leerzeichen umgewandelt, führt zu einer falsch dekodierten Zeichenfolge. /ist sicher in einem get-Parameter-Paar. =befindet sich immer am Ende der Base64-codierten Zeichenfolge und die Serverseite kann =direkt auflösen .
Ich vermute, dass dies richtig ist, da die Experimente, die ich mit der Base64-Codierung (ohne URL-Codierung) durchgeführt habe, erfolgreich waren, aber ich frage mich, ob Sie eine Dokumentation bereitstellen können, um dies zu sichern?
Sean the Bean
1
Sie sagen "immer sicher", aber dann sagen Sie "normalerweise kein +". Also widersprichst du dir. Das + -Zeichen kann Probleme verursachen, wenn Sie es in Ihrer base64-Zeichenfolge haben.
Antworten:
Nein, Sie müssten es url-codieren, da base64-Zeichenfolgen die Zeichen "+", "=" und "/" enthalten können, die die Bedeutung Ihrer Daten ändern können - sehen Sie aus wie ein Unterordner.
Gültige base64-Zeichen sind unten aufgeführt.
quelle
Es gibt zusätzliche base64-Spezifikationen. (Einzelheiten finden Sie in der Tabelle hier ). Im Wesentlichen benötigen Sie jedoch 65 Zeichen zum Codieren: 26 Kleinbuchstaben + 26 Großbuchstaben + 10 Ziffern = 62.
Sie benötigen zwei weitere ['+', '/'] und ein Füllzeichen '='. Aber keiner von ihnen ist url-freundlich, also benutze einfach verschiedene Zeichen für sie und du bist fertig. Die Standardzeichen aus der obigen Tabelle sind ['-', '_'], aber Sie können andere Zeichen verwenden, solange Sie sie gleich dekodiert haben und nicht mit anderen teilen müssen.
Ich würde empfehlen, nur Ihre eigenen Helfer zu schreiben. Wie diese aus den Kommentaren auf der PHP-Handbuchseite für base64_encode :
quelle
urlencode
wie in Rodrigo-Silveiras Antwort vorgeschlagen. Wenn Sie zwei neue Funktionen erstellen, um wenige Zeichen in der URL-Länge zu sparen, betreten Sie Ihr Haus durch das Fenster, anstatt nur die Tür zu benutzen.unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
sollte urlencodiert werden, schlage%2C
ich vor,._-
anstelle-_,
der einzigen Variante in en.wikipedia.org/wiki/Base64#Variants_summary_table zu verwenden , die das Trailing =@joeshmo Oder anstatt eine Hilfsfunktion zu schreiben, können Sie einfach die base64-codierte Zeichenfolge urlencodieren. Dies würde genau das Gleiche tun wie Ihre Hilfsfunktion, jedoch ohne die Notwendigkeit von zwei zusätzlichen Funktionen.
quelle
/
Zeichen, wenn Sie es nicht als GET-Parameter, sondern als Pfad in der URL übergeben. Es wird Ihren Weg ändern, wenn Sie nicht/
auf beiden Seiten durch etwas anderes ersetzen .Die Antwort lautet NEIN . Sie können nicht einfach einen Base64-codierten Parameter innerhalb einer URL-Abfragezeichenfolge übergeben, da Pluszeichen in ein Leerzeichen innerhalb des globalen Arrays $ _GET konvertiert werden. Mit anderen Worten, wenn Sie test.php gesendet haben? MyVar = stringwith + sign to
das Ergebnis wäre:
stringwith sign
Die einfache Möglichkeit, dies zu lösen, besteht darin, einfach
urlencode()
Ihre base64-Zeichenfolge zu erstellen, bevor Sie sie zur Abfragezeichenfolge hinzufügen, um die Zeichen +, = und / in% ## -Codes zu maskieren. Gibt zum Beispielurlencode("stringwith+sign")
zurückstringwith%2Bsign
Wenn Sie die Aktion verarbeiten, übernimmt PHP die automatische Dekodierung der Abfragezeichenfolge, wenn das globale $ _GET gefüllt wird. Zum Beispiel, wenn ich test.php? MyVar = stringwith% 2Bsign an gesendet habe
das Ergebnis wäre:
stringwith+sign
Sie nicht wollen,
urldecode()
die $ _GET String als + 's zurückgegeben werden in Leerzeichen umgewandelt werden.Mit anderen Worten, wenn ich dieselbe test.php gesendet habe? MyVar = stringwith% 2Bsign to
Das Ergebnis ist unerwartet:
stringwith sign
Es wäre sicher für
rawurldecode()
die Eingabe, jedoch redundant und daher unnötig.quelle
<br>
, sodass Sie nicht viel HTML eingeben müssen. Ich hoffe das hilft, ich habe deine Antwort ein wenig bearbeitet, um sie noch weiter zu verbessern.Ja und nein.
Der Basiszeichensatz von base64 kann in einigen Fällen mit herkömmlichen Konventionen kollidieren, die in URLs verwendet werden. Bei vielen Base64-Implementierungen können Sie den Zeichensatz jedoch so ändern, dass er besser mit URLs übereinstimmt, oder sogar mit einer (wie Pythons
urlsafe_b64encode()
).Ein weiteres Problem, mit dem Sie möglicherweise konfrontiert sind, ist die Begrenzung der URL-Länge bzw. das Fehlen einer solchen Begrenzung. Da Standards keine maximale Länge festlegen, können Browser, Server, Bibliotheken und andere Software, die mit dem HTTP-Protokoll arbeiten, ihre eigenen Grenzen definieren. Sie können sich diesen Artikel ansehen: WWW-FAQs: Was ist die maximale Länge einer URL?
quelle
Es ist eine base64url-Codierung, die Sie ausprobieren können. Es ist nur eine Erweiterung des obigen Codes von joeshmo.
quelle
Base64.getUrlEncoder().withoutPadding().encodeToString()
Ich denke nicht, dass dies sicher ist, da z. B. das Zeichen "=" in der Rohdatenbasis 64 verwendet wird und auch zur Unterscheidung der Parameter von den Werten in einem HTTP-GET verwendet wird.
quelle
Theoretisch ja, solange Sie die maximale Länge der URL und / oder der Abfragezeichenfolge für den Client oder Server nicht überschreiten.
In der Praxis kann es etwas schwieriger werden. Beispielsweise kann es eine HttpRequestValidationException in ASP.NET auslösen, wenn der Wert zufällig ein "Ein" enthält und Sie das nachfolgende "==" belassen.
quelle
Für die URL-sichere Codierung, wie
base64.urlsafe_b64encode(...)
in Python, funktioniert der folgende Code für mich zu 100%quelle
Ja, es ist immer sicher. Natürlich enthält base64:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
aber eine base64-codierte Zeichenfolge hat normalerweise keine+
.+
wird in ein Leerzeichen umgewandelt, führt zu einer falsch dekodierten Zeichenfolge./
ist sicher in einem get-Parameter-Paar.=
befindet sich immer am Ende der Base64-codierten Zeichenfolge und die Serverseite kann=
direkt auflösen .quelle