Decodificación de codificación URL (codificación porcentual)

101

Quiero decodificar la codificación de URL, ¿hay alguna herramienta integrada para hacer esto o alguien podría proporcionarme un sedcódigo que lo haga?

Busqué un poco a través de unix.stackexchange.com y en Internet, pero no pude encontrar ninguna herramienta de línea de comandos para decodificar la codificación de URL.

Lo que quiero hacer es simplemente editar un txtarchivo para que:

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

Y así.

Nombre para mostrar
fuente
stackoverflow.com/questions/6250698/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

107

Encontré estos revestimientos de Python one que hacen lo que quiere:

$ 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])"'

Ejemplo

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

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

Referencias

slm
fuente
Sé esto muy tarde, pero ¿hay alguna forma de hacerlo con la edición en el lugar?
DisplayName
@DisplayName: me parece una nueva Q. Lo preguntaría y haría referencia a este.
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
55
Tenga en cuenta que este es un Python 2; en los sistemas donde pythones 3 por defecto, esto dará como resultado un error. Cambiar pythona python2ayudas.
Ivan Kolmychek
44
Para python3que pueda utilizar en import urllib.parse as ullugar de import urllib as ul.
ibotty
61

sed

Pruebe la siguiente línea de comando:

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

o la siguiente alternativa usando echo -e:

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

Nota: es posible que la sintaxis anterior no se convierta +en espacios, y puede comer todas las nuevas líneas.


Puede definirlo como alias y agregarlo a sus archivos rc de shell :

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

Luego, cada vez que lo necesite, simplemente vaya con:

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

Golpetazo

Al crear secuencias de comandos, puede usar la siguiente sintaxis:

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

Sin embargo, la sintaxis anterior no manejará más ( +) correctamente, por lo que debe reemplazarlos con espacios a través de sed.

También puede usar lo siguiente urlencode()y las urldecode()funciones:

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}"
}

Tenga en cuenta que lo anterior urldecode()supone que los datos no contienen barra invertida.

Aquí hay una versión similar de Joel que se encuentra en: https://github.com/sixarm/urldecode.sh


bash + xxd

Función bash con xxdherramienta:

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
}

Se encuentra en el archivo GIST de Cdown , también en stackoverflow .


PHP

Usando PHP puedes probar el siguiente comando:

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

o solo:

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

Úselo -Rpara entrada de línea múltiple.


Perl

En Perl puedes usar URI::Escape.

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

O para procesar un archivo:

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

awk

Trate anon solución:

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

Nota: El parámetro -nes específico de GNU awk.

Consulte: Uso de awk printf para codificar el texto .

decodificar nombres de archivo

Si necesita eliminar la codificación de URL de los nombres de archivo, use la deurlnameherramienta de renameutils(p deurlname *.*. Ej .).

Ver también:


Relacionado:

kenorb
fuente
1
awk: Como esto hace uso de una función de biblioteca chr(), existe una alta probabilidad de que solo funcione en GNU awk ( gawk). Sin embargo, en este caso casi no habrá equivalente para POSIX awk, porque la -nopción (que permite argumentos no decimales) ES una awkespecialidad de GNU .
syntaxerror
Su primer sedcódigo me da xargs: argument line too longun archivo con ≥2164 líneas.
Gavilán
2
Sus soluciones involucradas printfno tienen en cuenta que la URL puede contener signos de porcentaje escapado como %25. Los pasa a printf sin escapar de ellos para printf con otro signo de porcentaje como %%.
josch
1
La versión bash requiere local LC_ALL=Cen la parte superior, de lo contrario, todos los caracteres anchos (es decir, japonés, chino, etc.) no se dividen correctamente en bytes.
Phernost
18

Hay una función incorporada para eso en la biblioteca estándar de Python. En Python 2, es urllib.unquote.

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

O para procesar un archivo:

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

En Python 3, es urllib.parse.unquote.

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

O para procesar un archivo:

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

En Perl puedes usar URI::Escape.

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

O para procesar un archivo:

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

Si desea apegarse a las herramientas portátiles POSIX, es incómodo, porque el único candidato serio es awk, que no analiza los números hexadecimales. Consulte Uso de awk printf para codificar el texto de url para obtener ejemplos con implementaciones comunes de awk, incluido BusyBox.

Gilles
fuente
10

Si desea utilizar un sedcomando simple , utilice lo siguiente:

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'

Pero es más conveniente crear un script como (por ejemplo sedscript):

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

Luego sed -f sedscript < old > new, ejecute , que saldrá como lo desee.


Para facilitar, el comando urlencodetambién está disponible directamente en el gridsite-clientspaquete se puede instalar desde ( sudo apt-get install gridsite-clientsen el sistema Ubuntu / Debian).

NOMBRE

    urlencode: convierte cadenas ao desde un formulario codificado en URL
SINOPSIS

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

DESCRIPCIÓN

    urlencode codifica cadenas de acuerdo con RFC 1738.

    Es decir, los caracteres A- Z a- z 0- 9 . _y -se pasan sin modificaciones, pero todos los demás caracteres se representan como% HH, donde HH es su representación ASCII hexadecimal en mayúsculas de dos dígitos. Por ejemplo, la URL se http://www.gridpp.ac.uk/convierte enhttp%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencodeConvierte cada carácter en todas las cadenas dadas en la línea de comando. Si se dan varias cadenas, se concatenan con espacios de separación antes de la conversión.

OPCIONES
    -m
      En lugar de una conversión completa, realice GridSite "codificación de URL moderada" en la que AZ az 0-9. = - _ @ y / se pasan sin modificaciones. Esto da como resultado cadenas ligeramente más legibles para los humanos, pero la aplicación debe estar preparada para crear o simular los directorios implicados por cualquier barra inclinada.
    -d
      Realice la decodificación de URL en lugar de la codificación, de acuerdo con RFC 1738. Las cadenas% HH y% hh se convierten y otros caracteres se pasan sin modificar, con la excepción de que +se convierte en espacio.

Ejemplo de decodificación de URL:

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

$ urlencode -d "Example: %21, %22, . . . , %29 etc"
Example: !, ", . . . , ) etc
Pandya
fuente
Para tutorial de sed visita
Pandya
44
Esta es una mala solución, ya que requiere codificar todos los caracteres. Este problema se ejemplifica cuando su código falta la %20secuencia de escape que se usa con frecuencia .
Overv
@Overv que acabo de revisar
Pandya
Además, es posible que desee verificar dos s/%26/&/gveces lo que hace. (Lo arreglé.)
G-Man
9

Perl one liner:

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

Ejemplo:

$ echo '%21%22' |  perl -pe 's/\%(\w\w)/chr hex $1/ge'
!"
Adrian Pronk
fuente
1
Esta respuesta es atractiva cuando no desea lidiar con la instalación de módulos perl.
Sridhar Sarnobat
1
Solo uno que funcionó elegantemente para mí en MacOS.
Qix
7

No puedo comentar sobre la mejor respuesta en este hilo , así que aquí está el mío.

Personalmente, uso estos alias para la codificación y decodificación de 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])"'

Ambos comandos le permiten convertir datos, pasados ​​como un argumento de línea de comandos o leerlos desde una entrada estándar , porque ambos de una línea verifican si hay argumentos de línea de comandos (incluso vacíos) y los procesan o simplemente leen la entrada estándar de lo contrario.


actualizar 2017-05-23 (codificación de barra)

En respuesta al comentario de @ Bevor.

Si también necesita codificar la barra oblicua, simplemente agregue un segundo argumento vacío a la función de comillas, entonces la barra también se codificará.

Entonces, finalmente el urlencode alias en bash se ve así:

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

Ejemplo

$ 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
DIG mbl
fuente
1
No codifica barras inclinadas.
Bevor
@Bevor: ¿Ejemplo?
DIG mbl
Agregue una barra diagonal al código urlen "Проба пера" -> resultado: la barra diagonal no está codificada.
Bevor
1
@Bevor: Tienes razón. Gracias por tu comentario. También cambiaré mi respuesta para reflejar su comentario.
DIG mbl
4

Y otro enfoque de Perl:

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

    print $uri->decode($_)
}

Deberá instalar el URI::Encodemódulo. En mi Debian, simplemente podría ejecutar

sudo apt-get install liburi-encode-perl

Luego, ejecuté el script anterior en un archivo de prueba que contiene:

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

El resultado fue (había guardado el script como foo.pl):

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

Una respuesta en (principalmente Posix) shell:

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

Explicación:

  • -e 's/+/ /gtransforma cada uno +en el espacio (como se describe en la norma de codificación de URL)
  • -e 's/%\(..\)/\\\\x\1/g'transformar cada uno %XXde \\xXX. Observe que uno de \ellos será eliminado al citar las reglas.
  • El printf interno está ahí para pasar la entrada a sed. Podemos reemplazarlo por cualquier otro mecanismo
  • El printf externo interpreta las \\xXXsecuencias y muestra el resultado.

Editar:

Dado %que siempre se debe interpretar en URL, es posible simplificar esta respuesta. Además, creo que es más limpio de usar en xargslugar de comillas inversas (gracias a @josch).

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

Desafortunadamente, (como notó @josch) ninguna de estas soluciones es compatible con Posix ya que la \xsecuencia de escape no está definida en Posix.

Jérôme Pouiller
fuente
Bienvenido a U&L. Quizás podría explicar esta respuesta y cómo funciona. En general, preferimos que nuestras respuestas sean largas con detalles, no solo fragmentos de código.
slm
Realmente me gusta esta respuesta porque es completa, portátil y no requiere programas externos más pesados ​​como perl o python. Funciona bien para mi
Steve Wills
1
Gran solución Y aún más corto y más inteligente: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. La -eopción puede omitirse aquí, de hecho ...
syntaxerror
1
@josch Tienes razón, printfestá integrado dashy no reconoce el \xescape. Puede usar en /usr/bin/printflugar de printfpara que funcione. Normalmente, debería poder usarlo command printf, pero parece que no funciona como debería. Continúa utilizando incorporado.
Jérôme Pouiller
1
@Jezz, de hecho, el soporte para \xescapar no es parte de POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html Durante mis pruebas vi otro problema. Es posible que desee reemplazar su ..expresión regular [a-zA-Z0-9][a-zA-Z0-9]porque, de lo contrario, la entrada como '%%%' fallará. También agregué s/%/%%/gal final para asegurarme de escapar de los porcentajes para printf.
josch
1

Solo concha:

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

Agregue --o %bpara evitar que los argumentos que comienzan con un guión se traten como opciones.

En zsh ${x//%/a}agrega aal final pero ${x//\%/a}reemplaza %con a.

Lri
fuente
1

Aquí están los bits relevantes de otro script (que robé descaradamente de mi script de descarga de youtube.com de otra respuesta) que he escrito antes. Utiliza sedy el shell para construir un urldecode que funcione.

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

No juro que sea completo, y de hecho lo dudo, pero manejó YouTube con suficiente seguridad.

mikeserv
fuente
1

Aquí hay una función BASH para hacer exactamente eso:

function urldecode() {
        echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g")
}
Adi D
fuente
funciona como encanto
AbdElraouf Sabri
0

Otra solución usando ruby ​​(la respuesta aceptada de Python no estaba funcionando para mí)

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

Ejemplo

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

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