Décodage du codage d'URL (codage en pourcentage)


101

Je souhaite décoder le codage d'URL. Existe-t-il un outil intégré permettant de le faire ou est-ce que quelqu'un pourrait me fournir un sedcode qui le fera?

J'ai un peu cherché sur unix.stackexchange.com et sur Internet, mais je n'ai trouvé aucun outil en ligne de commande pour décoder le codage des URL.

Ce que je veux faire, c'est simplement éditer un txtfichier afin que:

  • %21 devient !
  • %23 devient #
  • %24 devient $
  • %26 devient &
  • %27 devient '
  • %28 devient (
  • %29 devient )

Etc.


Réponses:


107

Vous avez trouvé ces liners Python one qui font ce que vous voulez:

$ alias urldecode='python -c "import sys, urllib as ul; \
    print ul.unquote_plus(sys.argv[1])"'

$ alias urlencode='python -c "import sys, urllib as ul; \
    print ul.quote_plus(sys.argv[1])"'

Exemple

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B

Références


Je le sais très tard, mais y a-t-il moyen de faire cela avec l'édition en place?
DisplayName

@ NomDisplay - sonne comme un nouveau Q pour moi. Je demanderais, et référence à celui-ci.
slm

15
streaming:cat your_lovely_file.csv| python -c "import sys, urllib as ul; [sys.stdout.write(ul.quote_plus(l)) for l in sys.stdin]"
kirill_igum

5
Notez qu'il s'agit d'un Python 2; sur les systèmes où pythonest 3 par défaut, cela entraînera une erreur. Changer pythonpour python2aider.
Ivan Kolmychek

4
Pour python3vous pouvez utiliser import urllib.parse as ulau lieu de import urllib as ul.
ibotty

61

sed

Essayez la ligne de commande suivante:

$ sed 's@+@ @g;s@%@\\x@g' file | xargs -0 printf "%b"

ou l'alternative suivante en utilisant echo -e:

$ sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' file | xargs echo -e

Remarque: La syntaxe ci-dessus ne peut pas être convertie +en espaces et peut englober toutes les nouvelles lignes.


Vous pouvez le définir comme alias et l'ajouter à vos fichiers rc de shell :

$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'

Ensuite, chaque fois que vous en avez besoin, il vous suffit de vous rendre avec

$ echo "http%3A%2F%2Fwww" | urldecode
http://www

Frapper

Lors de la création de scripts, vous pouvez utiliser la syntaxe suivante:

input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")

Cependant, la syntaxe ci-dessus ne gérera pas pluses ( +) correctement, vous devez donc les remplacer par des espaces sed.

Vous pouvez également utiliser les fonctions urlencode()et urldecode()suivantes:

urlencode() {
    # urlencode <string>
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done
}

urldecode() {
    # urldecode <string>

    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

Notez que ci-dessus urldecode()suppose que les données ne contiennent pas de barre oblique inverse.

Voici une version similaire de Joel disponible sur: https://github.com/sixarm/urldecode.sh


bash + xxd

Fonction Bash avec xxdoutil:

urlencode() {
  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf "$c" | xxd -p -c1 | while read x;do printf "%%%s" "$x";done
  esac
done
}

Trouvé dans le fichier gist de cdown , également à stackoverflow .


PHP

En utilisant PHP, vous pouvez essayer la commande suivante:

$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas

ou juste:

php -r 'echo urldecode("oil+and+gas");'

Utilisez cette option -Rpour la saisie de plusieurs lignes.


Perl

En Perl, vous pouvez utiliser URI::Escape.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

Ou pour traiter un fichier:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

awk

Essayez une solution unique :

awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..

Remarque: Le paramètre -nest spécifique à GNU awk.

Voir: Utilisation de awk printf pour urldecode text .

décodage des noms de fichiers

Si vous devez supprimer le codage d’URL des noms de fichiers, utilisez l’ deurlnameoutil de renameutils(par exemple deurlname *.*).

Voir également:


Apparenté, relié, connexe:


1
awk: Comme cela utilise une fonction de bibliothèque chr(), il y a une forte probabilité que cela fonctionne uniquement sur GNU awk ( gawk). Cependant, dans ce cas, il n’aura guère d’équivalent pour POSIX awk, car l’ -noption (autoriser les arguments non décimaux) EST UNE awkspécialité de GNU .
syntaxerror

Votre premier sedcode me donne xargs: argument line too longpour un fichier avec ≥2164 lignes.
Sparhawk

2
Vos solutions impliquant printfne tiennent pas compte du fait que l’URL peut contenir des signes de pourcentage échappés, tels que %25. Vous les transmettez à printf sans les échapper pour printf avec un autre signe de pourcentage comme %%.
josch

1
La version bash nécessite local LC_ALL=Cau début, sinon tous les caractères larges (japonais, chinois, etc.) ne sont pas correctement décomposés en octets.
Phernost


18

Il existe une fonction intégrée pour cela dans la bibliothèque standard Python. En Python 2, c'est urllib.unquote.

decoded_url=$(python2 -c 'import sys, urllib; print urllib.unquote(sys.argv[1])' "$encoded_url")

Ou pour traiter un fichier:

python2 -c 'import sys, urllib; print urllib.unquote(sys.stdin.read())' <file >file.new &&
mv -f file.new file

En Python 3, c'est urllib.parse.unquote.

decoded_url=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' "$encoded_url")

Ou pour traiter un fichier:

python3 -c 'import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))' <file >file.new &&
mv -f file.new file

En Perl, vous pouvez utiliser URI::Escape.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

Ou pour traiter un fichier:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

Si vous souhaitez vous en tenir aux outils portables POSIX, c'est délicat, car le seul candidat sérieux est awk, qui n'analyse pas les nombres hexadécimaux. Voir Utilisation de awk printf pour urldecode text pour des exemples d'implémentations courantes de awk, y compris BusyBox.


10

Si vous souhaitez utiliser une sedcommande simple , utilisez les éléments suivants:

sed -e 's/%21/!/g' -e 's/%23/#/g' -e 's/%24/$/g' -e 's/%26/\&/g' -e "s/%27/'/g" -e 's/%28/(/g' -e 's/%29/)/g'

Mais il est plus pratique de créer un script du type (par exemple sedscript):

s/%21/!/g
s/%23/#/g
s/%24/$/g
s/%26/\&/g
s/%27/'/g
s/%28/(/g
s/%29/)/g

Ensuite, lancez le programme sed -f sedscript < old > new, qui sortira comme vous le souhaitez.


Pour plus de facilité, la commande urlencodeest également disponible directement dans le gridsite-clientspackage sur lequel vous pouvez installer (par le sudo apt-get install gridsite-clientssystème Ubuntu / Debian).

NOM

    urlencode - convertit des chaînes en ou à partir d'une forme encodée en URL
SYNOPSIS

    urlencode [-m|-d] string [string ...]

LA DESCRIPTION

    urlencode code pour les chaînes selon RFC 1738.

    Autrement dit, les caractères A- Z a- z 0- 9 . _et -sont passés à travers non modifiée, mais tous les autres personnages sont représentés en% HH, où HH est leur représentation hexadécimale ASCII en majuscules à deux chiffres. Par exemple, l'URL http://www.gridpp.ac.uk/devienthttp%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencodeconvertit chaque caractère dans toutes les chaînes indiquées sur la ligne de commande. Si plusieurs chaînes sont données, elles sont concaténées avec des espaces de séparation avant la conversion.

LES OPTIONS
    -m
      Au lieu de la conversion complète, faites GridSite "encodage d'URL doux" dans lequel AZ az 0-9. = - _ @ et / sont passés non modifiés. Cela se traduit par des chaînes légèrement plus lisibles par l'homme, mais l'application doit être prête à créer ou à simuler les répertoires impliqués par des barres obliques.
    -d
      Décodez les URL plutôt que de les coder, conformément à la norme RFC 1738. Les chaînes% HH et% hh sont converties et les autres caractères sont transmis sans modification, à l’exception de la +conversion en espace.

Exemple d'URL de décodage:

$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f"
http://unix.stackexchange.com/

$ urlencode -d "Example: %21, %22, . . . , %29 etc"
Example: !, ", . . . , ) etc

Pour le tutoriel sur la sed visite
Pandya,

4
C'est une mauvaise solution car elle nécessite de coder en dur chaque caractère. Ce problème est illustré par le fait que votre code manque la %20séquence d'échappement souvent utilisée .
Surv

@Overv Je viens de réviser
Pandya

Aussi, vous voudrez peut-être vérifier ce qui se s/%26/&/gpasse. (Je l'ai corrigé.)
G-Man le

9

Perl une doublure:

$ perl -pe 's/\%(\w\w)/chr hex $1/ge'

Exemple:

$ echo '%21%22' |  perl -pe 's/\%(\w\w)/chr hex $1/ge'
!"

1
Cette réponse est intéressante lorsque vous ne souhaitez pas installer de modules Perl.
Sridhar Sarnobat

1
Un seul qui a fonctionné avec élégance pour moi sur MacOS.
Qix


7

Je ne peux pas commenter la meilleure réponse dans ce fil , alors voici le mien.

Personnellement, j'utilise ces alias pour le codage et le décodage d'URL:

alias urlencode='python -c "import urllib, sys; print urllib.quote(  sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

alias urldecode='python -c "import urllib, sys; print urllib.unquote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

Les deux commandes vous permettent de convertir des données, transmises en tant qu'argument de ligne de commande ou de les lire à partir d' une entrée standard , car les deux opérateurs vérifient s'il existe des arguments de ligne de commande (même vides) et les traitent ou lisent simplement une entrée standard.


mise à jour 2017-05-23 (codage par barre oblique)

En réponse au commentaire de @ Bevor.

Si vous devez également encoder la barre oblique, ajoutez simplement un deuxième argument vide à la fonction quote, la barre oblique sera également codée.

Donc, finalement, urlencode alias dans bash ressemble à ceci:

alias urlencode='python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")"'

Exemple

$ urlencode "Проба пера/Pen test"
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ echo "Проба пера/Pen test" | urlencode
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ urldecode %D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test
Проба пера/Pen test

$ echo "%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test" | urldecode
Проба пера/Pen test

$ urlencode "Проба пера/Pen test" | urldecode
Проба пера/Pen test

$ echo "Проба пера/Pen test" | urlencode | urldecode
Проба пера/Pen test

1
Ne pas coder les barres obliques.
Bevor

@Bevor: Exemple?
DIG mbl

Ajouter une barre oblique à l'urlencode "Проба пера" -> résultat: La barre oblique n'est pas codée.
Bevor

1
@ Bevor: Vous avez raison. Merci pour votre commentaire. Je modifierai également ma réponse pour refléter votre commentaire.
DIG mbl

4

Et une autre approche Perl:

#!/usr/bin/env perl
use URI::Encode;
my $uri     = URI::Encode->new( { encode_reserved => 0 } );
while (<>) {

    print $uri->decode($_)
}

Vous devrez installer le URI::Encodemodule. Sur ma Debian, je pourrais simplement courir

sudo apt-get install liburi-encode-perl

Ensuite, j'ai exécuté le script ci-dessus sur un fichier test contenant:

http://foo%21asd%23asd%24%26asd%27asd%28asd%29

Le résultat était (j'avais enregistré le script sous foo.pl):

$ ./foo.pl
http://foo!asd#asd$&asd'asd(asd)

3

Une réponse en shell (principalement Posix):

$ input='%21%22'
$ printf "`printf "%s\n" "$input" | sed -e 's/+/ /g' -e 's/%\(..\)/\\\\x\1/g'`"
!"

Explication:

  • -e 's/+/ /gtransforme chacun +dans l'espace (comme décrit dans la norme de codage d'URL)
  • -e 's/%\(..\)/\\\\x\1/g'transformer chacun %XXen \\xXX. Remarquez que l'un \sera supprimé en citant des règles.
  • Le printf interne est juste là pour transmettre une entrée à sed. Nous pouvons le remplacer par tout autre mécanisme
  • Le printf externe interprète les \\xXXséquences et affiche le résultat.

Modifier:

Puisque %doit toujours être interprété dans les URL, il est possible de simplifier cette réponse. En complément, je pense qu'il est plus propre à utiliser au xargslieu de backquotes (grâce à @josch).

$ input='%21%22+%25'
$ printf "%s\n" "$input" | sed -e 's/+/ /g; s/%/\\x/g' | xargs -0 printf
!" %

Malheureusement, (comme @josch l’a remarqué), aucune de ces solutions n’est conforme à Posix car \xla séquence d’échappement n’est pas définie dans Posix.


Bienvenue chez U & L. Peut-être pourriez-vous expliquer cette réponse et son fonctionnement. Nous préférons généralement que nos réponses soient longues avec des détails, pas seulement des extraits de code.
slm

J'aime beaucoup cette réponse car elle est complète, portable et ne nécessite pas de programmes externes plus lourds comme perl ou python. Fonctionne bien pour moi.
Steve Wills

1
Excellente solution. Et encore plus court et plus intelligemment: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. L' -eoption peut être omise ici en fait ...
syntaxerror

1
@ josch Vous avez raison, il printfest intégré dashet il ne reconnaît pas l' \xévasion. Vous pouvez utiliser /usr/bin/printfau lieu de printfpour le faire fonctionner. Normalement, vous devriez pouvoir utiliser command printf, mais cela ne semble pas fonctionner comme il se doit. Il continue à utiliser intégré.
Jérôme Pouiller

1
@Jezz en effet, le support pour \xéchapper ne fait pas partie de POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html Au cours de mes tests, j'ai constaté un autre problème. Vous voudrez peut-être remplacer votre ..expression rationnelle par [a-zA-Z0-9][a-zA-Z0-9]car sinon, une entrée telle que '%%%' échouera. J'ai aussi ajouté s/%/%%/gà la fin pour m'assurer d'échapper aux pourcentages pour printf.
josch

1

Shell seulement:

$ x='a%20%25%e3%81%82';printf "${x//\%/\\x}"
a %あ

Ajoutez --ou %bempêchez les arguments commençant par un tiret d'être traités comme des options.

Dans zsh ${x//%/a}ajoute aà la fin, mais ${x//\%/a}remplace %par a.


1

Voici les extraits pertinents d'un autre script (que j'ai simplement volé sans vergogne de mon script de téléchargement youtube.com d'une autre réponse) que j'ai écrits auparavant. Il utilise sedet le shell pour construire un urldecode fonctionnel.

set \! \" \# \$ \% \& \' \( \) \* \ \+ \, \/ \: \; \= \? \@ \[ \]
for c do set "$@" "'$c" "$c"; shift; done
curl -s "$url" | sed 's/\\u0026/\&/g;'"$(
    printf 's/%%%X/\\%s/g;' "$@"
)"

Je ne jurerai pas que c'est complet - et en fait j'en doute - mais il a sûrement géré youtube.


1

Voici une fonction BASH pour faire exactement cela:

function urldecode() {
        echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g")
}

fonctionne à merveille
AbdElraouf Sabri le

0

Une autre solution utilisant ruby ​​(la réponse acceptée par Python ne fonctionnait pas pour moi)

alias urldecode='ruby -e "require \"cgi\"; puts CGI.unescape(ARGV[0])"'
alias urlencode='ruby -e "require \"cgi\"; puts CGI.escape(ARGV[0])"'

Exemple

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.