Avkodning av URL-kodning (procentkodning)

Jag vill avkoda URL-kodning, finns det något inbyggt verktyg för att göra detta eller kan någon ge mig en sed kod som kommer att göra detta?

Jag sökte lite igenom unix.stackexchange.com och på internet men jag kunde inte hitta något kommandoradsverktyg för avkodning url-kodning.

Vad jag vill göra är att helt enkelt redigera en txt -fil så att:

  • %21 blir !
  • %23 blir #
  • %24 blir $
  • %26 blir &
  • %27 blir "
  • %28 blir (
  • %29 blir )

Och så vidare.

Kommentarer

Svar

Hittade dessa Python one-liners som gör vad du vill:

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

Exempel

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

Referenser

Kommentarer

  • Jag vet detta mycket sent , men finns det något sätt jag kan göra detta med på plats redigering?
  • @DisplayName – låter som en ny Q för mig. Jag frågar ’ och refererar till den här.
  • 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]"
  • Se @DIG mbl ’ s svar för nästa som fungerar med stdin.

Svar

sed

Testa följande kommandorad:

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

eller följande alternativ med echo -e:

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

Obs! Syntaxen ovan kan inte konvertera + till mellanslag och kan äta alla nya rader.


Du kan definiera det som alias och lägga till det i dina skal rc filer:

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

Varje gång du behöver det, gå bara med:

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

Bash

När du skriptar kan du använda följande syntax:

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

Men ovanför syntax vann inte handtaget plus (+) korrekt, så du måste ersätta dem med mellanslag via sed eller som föreslagits av @isaac , använd följande syntax:

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

Du kan också använda följande urlencode() och urldecode() funktioner:

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

Observera att ovanför urldecode() förutsätts att data inte innehåller något snedstreck.

Här liknar Joels version på: https://github.com/sixarm/urldecode.sh


bash + xxd

Bash-funktion med xxd verktyg:

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 } 

Finns i cdown ”s grundfil , även vid stackoverflow .


PHP

Med PHP kan du prova följande kommando:

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

eller bara:

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

Använd -R för flera radinmatningar.


Perl

I Perl du kan använda URI::Escape .

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

Eller för att bearbeta en fil:

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

awk

Försök anon lösning:

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

Obs: Parameter -n är specifik för GNU awk.

Se: Använda awk printf för att urkoda text .

avkodningsfilnamn

Om du behöver ta bort url-kodning från filnamnen använder du deurlname -verktyget från renameutils (t.ex. deurlname *.*).

Se även:


Relaterat:

Kommentarer

  • awk: Eftersom detta gör användning av en biblioteksfunktion, chr(), det är stor sannolikhet att det bara fungerar på GNU awk (gawk). I det här fallet kommer det dock knappast att finnas någon motsvarighet för POSIX awk, eftersom alternativet -n (tillåter icke-decimala argument) ÄR en GNU awk specialitet.
  • Dina lösningar som involverar printf tar inte hänsyn till att webbadressen kan innehålla undantagna procenttecken som %25. Du skickar dessa till printf utan att komma undan dem för printf med ett annat procentsignal som %%.
  • Bash-versionen kräver local LC_ALL=C högst upp, annars delas inte alla breda tecken (dvs. japanska, kinesiska, etc.) ordentligt in i byte.
  • github.com/SixArm/ urlencode.sh
  • Printf-versionerna fungerar inte ’ när du använder BSD-versionen av printf (t.ex. macOS), men det fungerar bra när du använder GNU Coreutils-version.

Svar

Det finns en inbyggd funktion för det i Pythons standardbibliotek. I Python 2 är det ”s urllib.unquote .

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

Eller för att bearbeta en fil:

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

I Python 3 är den ”s urllib.parse.unquote .

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

Eller för att bearbeta en fil:

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

I Perl kan du använda URI::Escape .

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

Eller för att bearbeta en fil:

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

Om du vill hålla dig till POSIX bärbara verktyg, det ” s besvärligt, för den enda seriösa kandidaten är awk, som inte tolkar hexadecimala tal. Se Använda awk printf för att urkoda text för exempel med vanliga awk-implementeringar, inklusive BusyBox.

Svar

Perl one liner:

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

Exempel:

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

Kommentarer

  • Detta svar är attraktivt när du inte ’ inte vill hantera installation av perl-moduler.
  • Endast en som fungerade elegant för mig på MacOS.
  • Om du vill lösa alla nivåer av URL-kodning på en gång finns ’ s också perl -pe 's/\%([[:xdigit:]]{2})/chr hex $1/ge while (/\%[[:xdigit:]]{2}/);' som kommer att avkoda alla %25xx kapslade kodningar

Svar

Om du vill använda ett enkelt sinnat sed -kommando, använd sedan följande:

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" 

Men det är bekvämare att skapa ett skript som (säg sedscript):

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

Kör sedan sed -f sedscript < old > new, vilket kommer att matas ut som du vill.


För enkelhetens skull är kommandot urlencode också tillgängligt direkt i gridsite-clients -paketet kan installeras från (av sudo apt-get install gridsite-clients i Ubuntu / Debian-systemet).

NAMN

    urlenkod – konvertera strängar till eller från URL-kodad form

SYNOPSIS

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

BESKRIVNING

    urlencode kodar strängar enligt RFC 1738.

    Det vill säga tecken AZ az 09 . _ och - skickas igenom omodifierade, men alla andra tecken representeras som% HH, där HH är deras två-d igit versaler med hexadecimal ASCII-representation. URL: en http://www.gridpp.ac.uk/ blir till exempel http%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencode varje tecken i alla strängar som anges på kommandoraden. Om flera strängar ges sammanfogas de med separata mellanslag före konvertering.

ALTERNATIV

    -m

      Istället för fullständig konvertering gör GridSite ”mild URL-kodning” där AZ az 0-9. = – _ @ och / skickas genom omodifierade. Detta resulterar i lite mer mänskliga läsbara strängar men applikationen måste vara beredd att skapa eller simulera kataloger som antyds av snedstreck.

    -d

      Gör snarare URL-avkodning än kodning, enligt RFC 1738.% HH och% hh strängar konverteras och andra tecken skickas omodifierade, med undantaget att + konverteras till utrymme.

Exempel på avkodnings-URL:

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

Kommentarer

  • För självstudier om sed besök
  • Detta är en dålig lösning, eftersom det kräver hårdkodning av varje tecken. Det här problemet exemplifieras genom att din kod saknar den ofta använda %20 escape-sekvensen.
  • @Overv I ’ har bara Reviderad
  • Du kanske också vill dubbelkolla vad s/%26/&/g gör. (Jag fixade det.)

Svar

Jag kan inte kommentera bästa svaret i den här tråden , så här är mitt.

Personligen använder jag dessa alias för URL-kodning och avkodning:

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

Båda kommandona låter dig konvertera data, skickade som kommandoradsargument eller läsa det från standardingång , eftersom båda enlinjerna kontrollerar om det finns kommandoradsargument (även tomma) och bearbetar dem eller bara läser standardinmatning annars.


uppdatera 23-05-2017 (snedkodning)

Som svar på @Bevors kommentar.

Om du måste också koda snedstrecket, lägg bara till ett tomt andra argument i offertfunktionen, då kommer snedstrecket också att kodas.

Så slutligen urlencode alias i bash ser ut så här:

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

Exam 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 

Kommentarer

  • Kodar inte snedstreck.
  • @Bevor : Exempel?
  • Lägg till ett snedstreck i webbadressen ” Проба пера ” – > resultat: Snedstreck är inte kodat.
  • @Bevor: Du har rätt. Tack för din kommentar. Jag kommer också att ändra mitt svar så att det återspeglar din kommentar.

Svar

GNU Awk

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

Svar

Och en annan Perl-metod:

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

Du måste installera URI::Encode -modulen. På min Debian kunde jag helt enkelt köra

sudo apt-get install liburi-encode-perl 

Sedan körde jag skriptet ovan på en testfil som innehöll:

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

Resultatet blev (jag hade sparat skriptet som foo.pl):

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

Svar

Ett svar i (mestadels Posix) skal:

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

Förklaring:

  • -e "s/+/ /g omvandlar varje + i rymden (som beskrivs i url-kodningsnorm)
  • -e "s/%\(..\)/\\\\x\1/g" förvandla varje %XX i \\xXX. Observera att en av \ kommer att tas bort genom att citera regler.
  • Den inre printf är precis där för att skicka inmatning till sed. Vi kan ersätta den med någon annan mekanism
  • Den yttre printf tolkar \\xXX sekvenser och visar resultatet.

Redigera:

Eftersom % alltid ska tolkas i webbadresser, det är möjligt att förenkla detta svar. Dessutom tycker jag att det är renare att använda xargs istället för backquotes (tack vare @josch).

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

Tyvärr, (som @josch märkte) är ingen av dessa lösningar Posix-kompatibla eftersom \x escape-sekvensen inte definieras i Posix.

Kommentarer

  • Välkommen till U & L. Du kanske kan förklara det här svaret och hur det fungerar. Vi föredrar vanligtvis att våra svar är långa med detaljer, inte bara kodavsnitt.
  • Jag gillar verkligen det här svaret eftersom det ’ är omfattande, bärbart och inte ’ t kräver extra tyngre externa program som perl eller python. Fungerar bra för mig.
  • Bra lösning. Och ännu kortare och smartare: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. Alternativet -e kan faktiskt utelämnas här …
  • @josch Du har rätt, printf är en inbyggd dash och det ’ t känner igen \x flyr. Du kan använda /usr/bin/printf istället för printf för att få det att fungera. Normalt bör du kunna använda command printf, men det verkar inte fungera som det ska. Det fortsätter att använda inbyggt.
  • @Jezz stöd för \x att fly är inte en del av POSIX: pubs.opengroup.org / onlinepubs / 9699919799 / utilities / printf.html Under mina tester såg jag ett annat problem. Du kanske vill ersätta din .. regex med [a-zA-Z0-9][a-zA-Z0-9] eftersom du annars skriver in som ’ %% % ’ misslyckas. Jag lade också till s/%/%%/g i slutet för att se till att undvika procentsatser för printf.

Svar

En annan lösning med ruby (accepterat pythonsvar fungerade inte för mig)

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

Exempel

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

Kommentarer

  • Används bara för att rubinera, och dessa uttalanden ser mindre ut. Dessutom ändrade jag till ARGF.read så att jag kan pipa in det som jag gör med många andra verktyg!

Svar

Här är en BASH-funktion för att göra exakt det:

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

Kommentarer

  • fungerar som charm
  • Om du vill konvertera + tecken till mellanslag och inte skapar några processer kan du använda detta: : "${1//+/ }" && echo -e "${_//%/\\x}"

Svar

Endast skal:

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

Lägg till -- eller %b för att förhindra att argument som börjar med en streck behandlas som alternativ.

I zsh ${x//%/a} lägger till a till slutet men ${x//\%/a} ersätter % med a.

Svar

Här är de relevanta bitarna från ett annat skript (som jag bara skamlöst stal från mitt nedladdningsskript för youtube.com från ett annat svar) Jag har skrivit tidigare. Den använder sed och skalet för att bygga upp en fungerande urldkod.

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

Jag brukar svära att det är omfattande – och faktiskt tvivlar jag på det – men det hanterade YouTube säkert nog.

Svar

Den enkla lösningen för kort strängar (skalet är långsamtwww):

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

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *