Non, ce n'est pas le cas - la question liée est plus récente. Cela fait donc de la question liée un double de celle-ci ...
serge
Réponses:
206
Non, vous devrez le coder par URL, car les chaînes base64 peuvent contenir les caractères "+", "=" et "/" qui pourraient modifier la signification de vos données - ressembler à un sous-dossier.
Le codage d'URL est une perte d'espace, d'autant plus que base64 lui-même laisse de nombreux caractères inutilisés.
Michał Górny
21
Je ne suis pas sûr de comprendre ce que vous dites - le codage d'URL ne modifiera aucun des caractères, à l'exception des trois derniers caractères de la liste ci-dessus, et c'est pour les empêcher d'être interprétés incorrectement car ils ont d'autres significations dans les URL. Il en va de même pour la base64, les données d'origine peuvent être binaires ou quoi que ce soit, mais elles sont encodées sous une forme qui peut être transmise facilement à l'aide de protocoles simples.
Thiyagaraj
3
Tout d'abord, vous devez également échapper à «+» car il peut être converti en espace. Deuxièmement, il y a au moins quelques caractères qui peuvent être utilisés en toute sécurité dans les URL et ne sont pas utilisés dans le jeu de caractères «standard». Votre méthode peut même augmenter la taille des données transférées trois fois dans certaines situations; tout en remplaçant ces caractères par d'autres fera l'affaire tout en conservant la même longueur. Et c'est aussi une solution tout à fait standard.
Michał Górny
8
en.wikipedia.org/wiki/Base64#URL_applications - il indique clairement que l'échappement «rend la chaîne inutilement plus longue» et mentionne la variante de jeu de caractères alternative.
Michał Górny
1
À cause de cette réponse, j'ai diagnostiqué mon problème comme étant exactement ce qu'il mentionnait. Certains des 64 caractères de base (+, /, =) ont été modifiés en raison du traitement des URL. Lorsque j'ai URL encodé la chaîne de base 64, le problème a été résolu.
Chuck Krutsinger
272
Il existe des spécifications supplémentaires en base64. (Voir le tableau ici pour les détails). Mais essentiellement, vous avez besoin de 65 caractères pour coder: 26 minuscules + 26 majuscules + 10 chiffres = 62.
Vous avez besoin de deux autres ['+', '/'] et un caractère de remplissage '='. Mais aucun d'entre eux n'est compatible avec les URL, alors utilisez simplement des caractères différents pour eux et vous êtes prêt. Les standards du graphique ci-dessus sont ['-', '_'], mais vous pouvez utiliser d'autres caractères tant que vous les décodez de la même manière, et que vous n'avez pas besoin de les partager avec les autres.
function base64_url_encode($input){return strtr(base64_encode($input),'+/=','._-');}function base64_url_decode($input){return base64_decode(strtr($input,'._-','+/='));}
Excellente solution, sauf que la virgule n'est pas sans réserve dans les URL. Je recommande d'utiliser '~' (tilde) ou '.' (point) à la place.
kralyk
11
@kralyk: Je recommande simplement d'utiliser urlencodecomme suggéré par la réponse de rodrigo-silveira. Créer deux nouvelles fonctions pour enregistrer quelques caractères en longueur d'URL, c'est comme entrer dans votre maison en passant par la fenêtre au lieu d'utiliser simplement la porte.
Marco Demaio
5
@MarcoDemaio, sans savoir comment il sera utilisé, il est impossible de dire qu'il ne s'agit que de quelques caractères. Chaque caractère encodé aura une longueur triple, et pourquoi "+++ ..." ne serait-il pas une chaîne base64 valide? Les URL ont des limites de navigateur, et tripler une URL peut vous faire atteindre ces limites.
leewz
10
@RandalSchwartz tilde est sans danger pour les URL. De RFC3986:unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
@joeshmo Ou au lieu d'écrire une fonction d'assistance, vous pouvez simplement encoder la chaîne encodée en base64. Cela ferait exactement la même chose que votre fonction d'assistance, mais sans avoir besoin de deux fonctions supplémentaires.
Le résultat n'est pas exactement le même. urlencode utilise 3 caractères pour encoder les caractères non valides et la solution de joeshmo en utilise 1. Ce n'est pas une grande différence, mais c'est quand même un gaspillage.
Josef Borkovec
1
@JosefBorkovec Vraiment? Cela signifierait également que le même nombre d'octets codés en base64-> url-> pourrait avoir une variété de longueurs résultantes différentes, tandis que l'autre solution donne une longueur prévisible, non?
humanityANDpeace
@humanityANDpeace Oui, l'urlencode est une solution de merde car il triple la taille de certaines chaînes base64. Vous ne pouvez pas non plus réutiliser le tampon car la sortie est plus grande que l'entrée.
Navin
4
L'extension de 1 à 3 caractères se produit sur 3 des 64 caractères en moyenne, il s'agit donc d'un surcoût de 9% (2 *
3/64
Soyez prudent avec le /caractère si vous le transmettez non pas comme paramètre GET, mais comme chemin d'accès dans l'URL. Cela changera votre chemin si vous ne remplacez pas /par quelque chose d'autre des deux côtés.
NeverEndingQueue
41
Note introductive Je suis enclin à publier quelques clarifications car certaines des réponses ici étaient un peu trompeuses (sinon incorrectes).
La réponse est NON , vous ne pouvez pas simplement passer un paramètre codé en base64 dans une chaîne de requête URL car les signes plus sont convertis en un ESPACE dans le tableau global $ _GET. En d'autres termes, si vous avez envoyé test.php? MyVar = stringwith + sign to
//test.phpprint $_GET['myVar'];
le résultat serait: stringwith sign
Le moyen le plus simple de résoudre ce problème consiste simplement à urlencode()insérer votre chaîne base64 avant de l'ajouter à la chaîne de requête pour échapper les caractères +, = et / aux codes% ##. Par exemple, urlencode("stringwith+sign")renvoiestringwith%2Bsign
Lorsque vous traitez l'action, PHP se charge de décoder automatiquement la chaîne de requête lors du remplissage de la variable globale $ _GET. Par exemple, si j'ai envoyé test.php? MyVar = stringwith% 2Bsign to
//test.phpprint $_GET['myVar'];
le résultat serait: stringwith+sign
Vous ne voulez pas de urldecode()la chaîne $ _GET retournée car les + seront convertis en espaces.
En d'autres termes, si j'ai envoyé le même test.php? MyVar = stringwith% 2Bsign to
Bonne réponse. Vous pouvez utiliser du code PHP sans les balises de début et de fin sur ce site si la question est balisée php (également le plus souvent, cela ressort clairement du contexte de la question). Si vous ajoutez deux espaces à la fin d'une ligne, vous verrez le <br>, donc pas besoin de taper beaucoup de code HTML. J'espère que cela aide, j'ai un peu modifié votre réponse pour encore plus l'améliorer.
hakre
Merci d'avoir mentionné que PHP décode l'URL pour vous. Cela m'évite de tomber dans un terrier de lapin.
Cocest
Bonne réponse -> Vous ne voulez pas urldecode () la chaîne $ _GET retournée car les + seront convertis en espaces. Il serait cependant sûr de rawurldecode () l'entrée
MarcoZen
14
Oui et non.
Le jeu de caractères de base de base64 peut dans certains cas entrer en collision avec les conventions traditionnelles utilisées dans les URL. Mais de nombreuses implémentations en base64 vous permettent de modifier le jeu de caractères pour mieux correspondre aux URL ou même de les accompagner (comme Python urlsafe_b64encode()).
Un autre problème auquel vous pouvez être confronté est la limite de longueur d'URL ou plutôt - l'absence de cette limite. Parce que les normes ne spécifient aucune longueur maximale, les navigateurs, serveurs, bibliothèques et autres logiciels fonctionnant avec le protocole HTTP peuvent définir ses propres limites. Vous pouvez consulter cet article: FAQ WWW: Quelle est la longueur maximale d'une URL?
Cela fonctionne pour les données encodées avec JavaBase64.getUrlEncoder().withoutPadding().encodeToString()
4
Je ne pense pas que cela soit sûr car, par exemple, le caractère "=" est utilisé dans la base brute 64 et est également utilisé pour différencier les paramètres des valeurs dans un HTTP GET.
En théorie, oui, tant que vous ne dépassez pas la longueur maximale de l'url et / ou de la chaîne de requête pour le client ou le serveur.
En pratique, les choses peuvent devenir un peu plus compliquées. Par exemple, il peut déclencher une HttpRequestValidationException sur ASP.NET si la valeur contient un "on" et que vous laissez dans le dernier "==".
Oui, c'est toujours sûr. bien sûr, base64 contient:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
mais une chaîne encodée en base64 n'en a généralement pas +. +sera converti en un espace vide, entraîne une chaîne décodée incorrecte. /est sûr dans une paire de paramètres get. =est toujours à la fin de la chaîne encodée en base64 et le côté serveur peut être résolu =directement.
Je suppose que c'est correct, car les expériences que j'ai faites avec le codage base64 (sans le codage url) ont réussi, mais je me demande s'il y a de la documentation que vous pourriez fournir pour sauvegarder cela?
Sean the Bean
1
vous dites "toujours en sécurité", mais vous dites "généralement pas de +". Donc vous vous contredisez. Le signe + semble causer des problèmes si vous l'avez dans votre chaîne base64.
Réponses:
Non, vous devrez le coder par URL, car les chaînes base64 peuvent contenir les caractères "+", "=" et "/" qui pourraient modifier la signification de vos données - ressembler à un sous-dossier.
Les caractères base64 valides sont ci-dessous.
la source
Il existe des spécifications supplémentaires en base64. (Voir le tableau ici pour les détails). Mais essentiellement, vous avez besoin de 65 caractères pour coder: 26 minuscules + 26 majuscules + 10 chiffres = 62.
Vous avez besoin de deux autres ['+', '/'] et un caractère de remplissage '='. Mais aucun d'entre eux n'est compatible avec les URL, alors utilisez simplement des caractères différents pour eux et vous êtes prêt. Les standards du graphique ci-dessus sont ['-', '_'], mais vous pouvez utiliser d'autres caractères tant que vous les décodez de la même manière, et que vous n'avez pas besoin de les partager avec les autres.
Je recommanderais simplement d'écrire vos propres assistants. Comme ceux des commentaires sur la page de manuel php pour base64_encode :
la source
urlencode
comme suggéré par la réponse de rodrigo-silveira. Créer deux nouvelles fonctions pour enregistrer quelques caractères en longueur d'URL, c'est comme entrer dans votre maison en passant par la fenêtre au lieu d'utiliser simplement la porte.unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
devrait être encodé en url%2C
, je suggère d'utiliser._-
au lieu de-_,
comme la seule variante de en.wikipedia.org/wiki/Base64#Variants_summary_table qui garde le suivi =@joeshmo Ou au lieu d'écrire une fonction d'assistance, vous pouvez simplement encoder la chaîne encodée en base64. Cela ferait exactement la même chose que votre fonction d'assistance, mais sans avoir besoin de deux fonctions supplémentaires.
la source
/
caractère si vous le transmettez non pas comme paramètre GET, mais comme chemin d'accès dans l'URL. Cela changera votre chemin si vous ne remplacez pas/
par quelque chose d'autre des deux côtés.La réponse est NON , vous ne pouvez pas simplement passer un paramètre codé en base64 dans une chaîne de requête URL car les signes plus sont convertis en un ESPACE dans le tableau global $ _GET. En d'autres termes, si vous avez envoyé test.php? MyVar = stringwith + sign to
le résultat serait:
stringwith sign
Le moyen le plus simple de résoudre ce problème consiste simplement à
urlencode()
insérer votre chaîne base64 avant de l'ajouter à la chaîne de requête pour échapper les caractères +, = et / aux codes% ##. Par exemple,urlencode("stringwith+sign")
renvoiestringwith%2Bsign
Lorsque vous traitez l'action, PHP se charge de décoder automatiquement la chaîne de requête lors du remplissage de la variable globale $ _GET. Par exemple, si j'ai envoyé test.php? MyVar = stringwith% 2Bsign to
le résultat serait:
stringwith+sign
Vous ne voulez pas de
urldecode()
la chaîne $ _GET retournée car les + seront convertis en espaces.En d'autres termes, si j'ai envoyé le même test.php? MyVar = stringwith% 2Bsign to
le résultat est inattendu:
stringwith sign
Il serait sûr pour
rawurldecode()
l'entrée, cependant, il serait redondant et donc inutile.la source
<br>
, donc pas besoin de taper beaucoup de code HTML. J'espère que cela aide, j'ai un peu modifié votre réponse pour encore plus l'améliorer.Oui et non.
Le jeu de caractères de base de base64 peut dans certains cas entrer en collision avec les conventions traditionnelles utilisées dans les URL. Mais de nombreuses implémentations en base64 vous permettent de modifier le jeu de caractères pour mieux correspondre aux URL ou même de les accompagner (comme Python
urlsafe_b64encode()
).Un autre problème auquel vous pouvez être confronté est la limite de longueur d'URL ou plutôt - l'absence de cette limite. Parce que les normes ne spécifient aucune longueur maximale, les navigateurs, serveurs, bibliothèques et autres logiciels fonctionnant avec le protocole HTTP peuvent définir ses propres limites. Vous pouvez consulter cet article: FAQ WWW: Quelle est la longueur maximale d'une URL?
la source
C'est un encodage base64url que vous pouvez essayer, sa juste extension du code de joeshmo ci-dessus.
la source
Base64.getUrlEncoder().withoutPadding().encodeToString()
Je ne pense pas que cela soit sûr car, par exemple, le caractère "=" est utilisé dans la base brute 64 et est également utilisé pour différencier les paramètres des valeurs dans un HTTP GET.
la source
En théorie, oui, tant que vous ne dépassez pas la longueur maximale de l'url et / ou de la chaîne de requête pour le client ou le serveur.
En pratique, les choses peuvent devenir un peu plus compliquées. Par exemple, il peut déclencher une HttpRequestValidationException sur ASP.NET si la valeur contient un "on" et que vous laissez dans le dernier "==".
la source
Pour un encodage sûr, comme
base64.urlsafe_b64encode(...)
en Python, le code ci-dessous fonctionne à 100% pour moila source
Oui, c'est toujours sûr. bien sûr, base64 contient:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
mais une chaîne encodée en base64 n'en a généralement pas+
.+
sera converti en un espace vide, entraîne une chaîne décodée incorrecte./
est sûr dans une paire de paramètres get.=
est toujours à la fin de la chaîne encodée en base64 et le côté serveur peut être résolu=
directement.la source