Decodificação de codificação de URL (porcentagem de codificação)

87

Desejo decodificar a codificação de URL. Existe alguma ferramenta interna para fazer isso ou alguém poderia me fornecer um código sed que fará isso?

Eu pesquisei um pouco através do unix.stackexchange.com e na internet, mas não encontrei nenhuma ferramenta de linha de comando para decodificação codificação de url.

O que eu quero fazer é simplesmente editar um arquivo txt para que:

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

E assim por diante.

    
por DisplayName 04.10.2014 / 15:13

12 respostas

88

Encontrei esses liners do Python que fazem o que você quer:

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

Exemplo

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

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

Referências

por 04.10.2014 / 15:28
53

sed

Experimente a seguinte linha de comando:

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

ou a seguinte alternativa usando echo -e :

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

Observação: a sintaxe acima pode não converter + em espaços e pode consumir todas as novas linhas.

Você pode defini-lo como alias e adicioná-lo ao seu arquivo rc :

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

Então, toda vez que precisar, basta ir com:

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

bash

Ao criar scripts, você pode usar a seguinte sintaxe:

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

No entanto, a sintaxe acima não processa os prós e contras ( + ) corretamente, então você precisa substituí-los por espaços com sed .

Você também pode usar as seguintes funções urlencode() e urldecode() :

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

Note that your urldecode() assumes the data contains no backslash.

bash + xxd

Função de bash com a ferramenta xxd :

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
}

Encontrado no arquivo gist do cdown , também em stackoverflow .

PHP

Usando o PHP, você pode tentar o seguinte comando:

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

ou apenas:

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

Use -R para várias entradas de linha.

Perl

Em Perl, você pode usar URI::Escape .

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

Ou para processar um arquivo:

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

awk

Tente a solução anon :

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

Nota: O parâmetro -n é específico para o GNU awk .

Veja: Usando awk printf para urldecode text .

decodificando nomes de arquivos

Se você precisar remover a codificação de URL dos nomes dos arquivos, use a ferramenta deurlname de renameutils (por exemplo, deurlname *.* ).

Veja também:

Relacionados:

por 27.02.2015 / 18:57
18

Existe uma função interna para isso na biblioteca padrão do Python. No Python 2, é urllib.unquote .

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

Ou para processar um arquivo:

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

No Python 3, é urllib.parse.unquote .

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

Ou para processar um arquivo:

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

Em Perl, você pode usar URI::Escape .

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

Ou para processar um arquivo:

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

Se você quiser se ater às ferramentas portáteis POSIX, é estranho, porque o único candidato sério é o awk, que não analisa números hexadecimais. Veja Usando awk printf para urldecode text para exemplos com implementações awk comuns, incluindo BusyBox .

    
por 04.10.2014 / 15:32
9

Se você quiser usar um comando sed simplista, use o seguinte:

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'

Mas é mais conveniente criar um script como (digamos, sedscript ):

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

Em seguida, execute sed -f sedscript < old > new , que será exibido como você deseja.

Para facilitar, o comando urlencode também está disponível diretamente no gridsite-clients package pode ser instalado de (por sudo apt-get install gridsite-clients no sistema Ubuntu / Debian).

NAME

    urlencode - convert strings to or from URL-encoded form
SYNOPSIS
    urlencode [-m|-d] string [string ...]

DESCRIPTION

    urlencode encodes strings according to RFC 1738.

    That is, characters A-Z a-z 0-9 . _ and - are passed through unmodified, but all other characters are represented as %HH, where HH is their two-digit upper-case hexadecimal ASCII representation. For example, the URL http://www.gridpp.ac.uk/ becomes http%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencode converts each character in all the strings given on the command line.  If multiple strings are given, they are concatenated with separating spaces before conversion.

OPTIONS
    -m
      Instead of full conversion, do GridSite "mild URL encoding" in which A-Z a-z 0-9 . = - _ @ and / are passed through unmodified.  This results in slightly more human-readable strings but the application must be prepared to create or simulate the directories implied by any slashes.
    -d
      Do URL-decoding rather than encoding, according to RFC 1738.  %HH and %hh strings are converted and other characters are passed through unmodified, with the exception that + is converted to space.

Exemplo de decodificação de URL:

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

$ urlencode -d "Example: %21, %22, . . . , %29 etc"
Example: !, ", . . . , ) etc
    
por 04.10.2014 / 16:15
7

GNU awk

#!/usr/bin/awk -fn
@include "ord"
BEGIN {
  RS = "%.."
}
{
  printf RT ? $0 chr("0x" substr(RT, 2)) : $0
}

Ou

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

Converter o URL do arquivo codificado por percentual em arquivo local no bash

    
por 05.10.2014 / 08:31
7

Não posso comentar a melhor resposta neste tópico , então aqui está a minha.

Pessoalmente, eu uso esses aliases para codificação e decodificação 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 os comandos permitem converter dados, passados como um argumento de linha de comando ou lê-los a partir de entrada padrão , porque ambos os marcadores verificam se há argumentos de linha de comando (mesmo os vazios) e processá-los ou apenas ler a entrada padrão de outra forma.

atualização 2017-05-23 (codificação de barra)

Em resposta ao comentário do @Bevor.

Se você também precisar codificar a barra, basta adicionar um segundo argumento vazio à função quote e, em seguida, a barra também será codificada.

Então, finalmente, urlencode alias em bash tem esta aparência:

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

Exemplo

$ 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
    
por 16.07.2015 / 01:43
6

Perl one liner:

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

Exemplo:

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

E outra abordagem Perl:

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

    print $uri->decode($_)
}

Você precisará instalar o módulo URI::Encode . No meu Debian, eu poderia simplesmente executar

sudo apt-get install liburi-encode-perl

Em seguida, executei o script acima em um arquivo de teste contendo:

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

O resultado foi (eu salvei o script como foo.pl ):

$ ./foo.pl
http://foo!asd#asd$&asd'asd(asd)
    
por 04.10.2014 / 15:32
3

Uma resposta na shell (principalmente Posix):

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

Explicação:

  • -e 's/+/ /g transforma cada + no espaço (conforme descrito na norma de codificação de URL)
  • -e 's/%\(..\)/\\x/g' transforma cada %XX em \xXX . Observe que um dos \ será removido por regras de cotação.
  • O printf interno está lá apenas para passar a entrada para o sed. Podemos substituí-lo por qualquer outro mecanismo
  • O printf externo interpreta \xXX sequências e exibe o resultado.

Editar:

Como % sempre deve ser interpretado em URLs, é possível simplificar essa resposta. Além disso, acho que é mais limpo usar xargs em vez de backquotes (graças a @josch).

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

Infelizmente, (como @josch notou) nenhuma dessas soluções são compatíveis com Posix, pois a sequência de escape \x não está definida no Posix.

    
por 05.12.2014 / 10:16
1

Apenas shell:

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

Adicione -- ou %b para evitar que argumentos iniciados com um traço sejam tratados como opções.

Em zsh ${x//%/a} adiciona a ao final, mas ${x//\%/a} substitui % por a .

    
por 08.10.2014 / 09:15
1

Aqui estão os bits relevantes de outro script (que eu simplesmente roubei do meu script de download do youtube.com de outra resposta) Eu escrevi antes. Ele usa sed e o shell para construir um urldecode funcional.

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

Eu não juro que é abrangente - e na verdade eu duvido - mas lidou com o youtube com certeza o suficiente.

    
por 05.12.2014 / 14:15
1

Aqui está uma função BASH para fazer exatamente isso:

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

me ajudou. espero que isso ajude você.

    
por 26.03.2016 / 14:30