Dekódování kódování URL (procento kódování)

Chci dekódovat kódování URL, existuje k tomu nějaký vestavěný nástroj nebo mi někdo může poskytnout sed kód, který to udělá?

Trochu jsem prohledával unix.stackexchange.com a na internetu, ale nenašel jsem žádný nástroj příkazového řádku pro dekódování kódování URL.

To, co chci udělat, je jednoduše na místě upravit soubor txt tak, aby:

  • %21 se stává !
  • %23 #
  • %24 se stává $
  • %26 se stává &
  • %27 se stává "
  • %28 se stává (
  • %29 stává se )

atd.

Komentáře

Odpověď

Nalezli tyto vložky Pythonu, které dělají, co chcete:

Python2

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

Python3

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

Příklad

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

Reference

Komentáře

  • Vím to velmi pozdě , ale existuje nějaký způsob, jak to udělat s úpravami na místě?
  • @DisplayName – zní mi to jako nové Q. ‚ Požádám o to a odkazuji na tento.
  • streamování: cat your_lovely_file.csv| python -c "import sys, urllib as ul; [sys.stdout.write(ul.quote_plus(l)) for l in sys.stdin]"
  • Viz odpověď @DIG mbl ‚ na odpověď, která funguje se stdin.

Odpověď

sed

Zkuste následující příkazový řádek:

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

nebo následující alternativu pomocí echo -e:

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

Poznámka: Výše uvedená syntaxe nemusí převádět + do mezer a může pojmout všechny nové řádky.


Můžete jej definovat jako alias a přidat jej do svých rc souborů:

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

Pak pokaždé, když to potřebujete, jednoduše použijte:

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

Bash

Při skriptování můžete použít následující syntaxi:

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

Výše uvedená syntaxe však nevyřeší klady (+) správně, takže je můžete nahradit mezerami pomocí sed nebo podle doporučení @isaac použijte následující syntaxi:

decoded=$(input=${input//+/ }; printf "${input//%/\\x}") 

Můžete také použít následující urlencode() a urldecode() funkce:

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

Všimněte si, že výše urldecode() předpokládá, že data neobsahují žádné zpětné lomítko.

Zde je podobná verze Joela nalezená na adrese: https://github.com/sixarm/urldecode.sh


bash + xxd

Bash funkce s nástrojem 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 } 

Nalezeno v cdown „s hlavním souborem , také na stackoverflow .


PHP

Pomocí PHP můžete vyzkoušet následující příkaz:

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

nebo jen:

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

Použijte -R pro víceřádkový vstup.


Perl

V Perlu vy může používat URI::Escape .

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

Nebo zpracovat soubor:

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

awk

Zkuste anon řešení:

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

Poznámka: Parametr -n je specifický pro GNU awk.

Viz: Použití awk printf k urldekódování textu .

dekódování názvů souborů

Pokud potřebujete odstranit kódování adres URL z názvů souborů, použijte nástroj deurlname z renameutils (např deurlname *.*).

Viz také:


Související:

Komentáře

  • awk: Díky tomu při použití funkce knihovny chr() je vysoká pravděpodobnost, že bude fungovat pouze na GNU awk (gawk). V tomto případě však pro POSIX awk téměř neexistuje ekvivalent, protože možnost -n (umožňující nedesítkové argumenty) JE specialita GNU awk.
  • Vaše řešení zahrnující printf nebere v úvahu, že adresa URL může obsahovat znaky procenta s únikem, například %25. Předáte je printf, aniž byste je unikli pro printf s jiným znakem procenta, jako je %%.
  • Verze bash vyžaduje local LC_ALL=C nahoře, jinak nebudou všechny široké znaky (tj. japonské, čínské atd.) správně rozděleny na bajty.
  • github.com/SixArm/ urlencode.sh
  • Verze printf nefungují ‚ při použití BSD verze printf (např. macOS), ale při použití Verze GNU Coreutils.

Odpověď

Ve standardní knihovně Pythonu je k tomu integrovaná funkce. V Pythonu 2 je to „s urllib.unquote .

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

Nebo zpracovat soubor:

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

V Pythonu 3 je to „s urllib.parse.unquote .

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

Nebo zpracovat soubor:

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

V Perlu můžete použít URI::Escape .

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

Nebo zpracovat soubor:

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

Pokud se chcete držet přenosných nástrojů POSIX, je to “ je to trapné, protože jediný vážný kandidát je awk, který nerozebere hexadecimální čísla. Příklady s běžnými implementacemi awk, včetně BusyBox, najdete v části Použití awk printf k urldecode textu .

Odpovědět

Perl jedna linka:

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

Příklad:

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

Komentáře

  • Tato odpověď je atraktivní, pokud se nechcete ‚ zabývat instalací modulů Perl.
  • Pouze jeden, který pro mě v systému MacOS fungoval elegantně.
  • Pokud chcete vyřešit všechny úrovně kódování adres URL najednou, existuje ‚ s také perl -pe 's/\%([[:xdigit:]]{2})/chr hex $1/ge while (/\%[[:xdigit:]]{2}/);' který dekóduje všechna %25xx vnořená kódování

odpověď

Pokud chcete použít jednoduchý sed příkaz, použijte následující:

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" 

Je však pohodlnější vytvořit skript jako (řekněme sedscript):

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

Poté spusťte program sed -f sedscript < old > new, který se bude zobrazovat podle vašich požadavků.


Pro usnadnění je příkaz urlencode k dispozici také přímo v gridsite-clients balíček lze nainstalovat z (pomocí sudo apt-get install gridsite-clients v systému Ubuntu / Debian).

NAME

    urlencode – převádí řetězce do nebo z formuláře kódovaného URL

SYNOPSIS

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

POPIS

    urlencode kóduje řetězce podle RFC 1738.

    To znamená, znaky AZ az 09 . _ a - procházejí nezměněnými, ale všechny ostatní znaky jsou reprezentovány jako% HH, kde HH je jejich dvojd igit velká hexadecimální reprezentace ASCII. Například adresa URL http://www.gridpp.ac.uk/ se změní na http%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencode každý znak ve všech řetězcích uvedených na příkazovém řádku. Pokud je zadáno více řetězců, jsou před převodem zřetězeny oddělujícími mezerami.

MOŽNOSTI

    -m

      Místo úplné konverze proveďte GridSite „mírné kódování URL“ ve kterém AZ az 0-9. = – _ @ a / jsou předávány beze změny. Výsledkem jsou o něco více čitelné řetězce, ale aplikace musí být připravena vytvořit nebo simulovat adresáře implikované lomítky.

    -d

      Provádějte spíše dekódování URL než kódování, podle RFC 1738. Řetězce% HH a% hh jsou převedeny a ostatní znaky procházejí nezměněnými, s výjimkou, že + je převeden na mezeru.

Příklad dekódovací adresy URL:

$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f" http://unix.stackexchange.com/ $ urlencode -d "Example: %21, %22, . . . , %29 etc" Example: !, ", . . . , ) etc 

Komentáře

  • Výukový program k sed návštěvě
  • Toto je špatné řešení, protože vyžaduje pevné zakódování každého znaku. Příkladem tohoto problému je, že ve vašem kódu chybí často používaná %20 úniková sekvence.
  • @Overv I ‚ jsem jen Upraveno
  • Možná budete chtít ještě jednou zkontrolovat, co s/%26/&/g dělá. (Opravil jsem to.)

Odpovědět

Nemohu komentovat nejlepší odpověď v tomto vlákně , takže tady je moje.

Osobně používám tyto aliasy pro kódování a dekódování 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])"" 

Oba příkazy umožňují převádět data, předávaná jako argument příkazového řádku nebo číst z standardní vstup , protože obě řádky kontrolují, zda existují argumenty příkazového řádku (i prázdné), a zpracovávají je nebo jen čtou jinak standardní vstup.


aktualizace 2017-05-23 (kódování lomítka)

v reakci na komentář @Bevor.

pokud také je třeba kódovat lomítko, stačí přidat prázdný druhý argument do funkce citace, poté se lomítko také zakóduje.

Takže nakonec urlencode alias v bash vypadá takto:

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

zkouška ple

$ 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 

Komentáře

  • Nekóduje lomítka.
  • @Bevor : Příklad?
  • Přidat lomítko do urlencode “ Проба пера “ – > výsledek: Slash není zakódován.
  • @Bevor: Máte pravdu. Děkuji za váš komentář. Změním také svoji odpověď tak, aby v ní byl zohledněn váš komentář.

Odpověď

GNU Awk

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

Odpověď

A další přístup Perlu:

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

Bude nutné nainstalovat modul URI::Encode. V mém Debianu jsem mohl jednoduše spustit

sudo apt-get install liburi-encode-perl 

Poté jsem spustil výše uvedený skript na testovací soubor obsahující:

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

Výsledek byl (skript jsem uložil jako foo.pl):

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

Odpovědět

Odpověď ve (většinou Posix) prostředí:

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

Vysvětlení:

  • -e "s/+/ /g transformuje každou + ve vesmíru (jak je popsáno v normě url-encode)
  • -e "s/%\(..\)/\\\\x\1/g" transformujte každý %XX v \\xXX. Všimněte si, že jeden z \ bude odstraněn pomocí pravidel citování.
  • Vnitřní printf je právě tam, aby předal vstup sed. Můžeme jej nahradit jakýmkoli jiným mechanismem
  • Vnější printf interpretuje \\xXX sekvence a zobrazuje výsledek.

Upravit:

Protože % by měl být vždy interpretován v adresách URL, tuto odpověď je možné zjednodušit. Kromě toho si myslím, že je čistší použít xargs místo backquotes (díky @josch).

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

Bohužel (jak si všiml @josch) žádné z těchto řešení nevyhovuje Posixu, protože \x úniková sekvence není v Posixu definována.

Komentáře

  • Vítejte v U & L. Možná byste mohli vysvětlit tuto odpověď a její fungování. Obecně dáváme přednost tomu, aby naše odpovědi byly dlouhé, s podrobnostmi, nejen s úryvky kódu.
  • Tato odpověď se mi opravdu líbí, protože je ‚ komplexní, přenosná a ‚ t vyžadují extra těžší externí programy jako perl nebo python. Funguje pro mě dobře.
  • Skvělé řešení. A ještě kratší a chytřejší: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. Možnost -e zde lze ve skutečnosti vynechat …
  • @josch Máte pravdu, printf je integrovaný dash a nerozpozná únik ‚ \x. Aby to fungovalo, můžete místo printf použít /usr/bin/printf. Normálně byste měli být schopni použít command printf, ale zdá se, že to nefunguje tak, jak by mělo. I nadále používá vestavěný.
  • @Jezz skutečně podpora pro \x únik není součástí POSIXu: pubs.opengroup.org / onlinepubs / 9699919799 / utilities / printf.html Během testů jsem viděl další problém. Možná budete chtít svůj .. regulární výraz nahradit [a-zA-Z0-9][a-zA-Z0-9], protože jinak zadejte jako ‚ %% % ‚ selže. Také jsem na konec přidal s/%/%%/g, abych se ujistil, že uniknou procenta pro printf.

Odpovědět

Jiné řešení využívající rubín (přijatá odpověď pythonu pro mě nefunguje)

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

Příklad

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

Komentáře

  • Právě se používá rubín a tato tvrzení vypadají menší. Také jsem se změnil na ARGF.read, abych jej mohl propojit jako s mnoha dalšími nástroji!

Odpověď

Tady je funkce BASH, která umožňuje přesně toto:

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

Komentáře

  • funguje jako kouzlo
  • Pokud chcete převést + znaky na mezery a nevytvářet žádné procesy, můžete použít toto: : "${1//+/ }" && echo -e "${_//%/\\x}"

odpověď

Pouze prostředí:

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

Přidat -- nebo %b zabráníte tomu, aby se s argumenty, které začínají pomlčkou, zacházelo jako s volbami.

V zsh ${x//%/a} na konec přidá a, ale ${x//\%/a} nahradí % a.

Odpověď

Zde jsou relevantní bity z jiného skriptu (který jsem nestydatě) ukradl můj skript pro stahování youtube.com z jiné odpovědi) Napsal jsem dříve. Využívá sed a shell k vytvoření funkčního urldecode.

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

Nebudu přísahat, že je komplexní – a ve skutečnosti o tom pochybuji – ale určitě to zvládlo youtube.

Odpověď

Jednoduché řešení pro krátké řetězce (shell je pomalý):

$ str="q+werty%3D%2F%3B" $ a=${str//+/ };printf "$(echo "${a//%/\\x}")\n" q werty=/; 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *