Komut satırında yüzde olarak kodlanmış dizeleri nasıl kodlayabilir ve kodunu çözebilirim?


31

Komut satırında yüzde kodlu (URL kodlanmış) dizeleri nasıl kodlayabilir ve kodunu çözebilirim ?

Bunu yapabilen bir çözüm arıyorum:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük

Siz de farklı kodlamalar eklemek ister misiniz? %E6ndr%FCkbana (standart) UTF8 gibi görünmüyor. Ya da sadece bir örnek?
düzenleme

@arrange Bunu yakaladığın için teşekkürler. Görünüşe göre, kötü elmaları çevrimiçi çeviriciler için arama sonuçları arasında seçtim .
ændrük

Yanıtlar:


35

Bu komutlar ne istersen onu yapar:

python -c "import urllib, sys; print urllib.quote(sys.argv[1])" æ
python -c "import urllib, sys; print urllib.unquote(sys.argv[1])" %C3%A6

Eğer olarak kodlamak boşluk istiyorsanız +, yerini urllib.quoteile urllib.quote_plus.

Sanırım onları takma isimlendirmek isteyeceksiniz ;-)


1
İlk satırın sonundaki æ karakteri nedir? Düzenleme: kendime cevap - Anladım, sadece UTF8 kodlanmış bir karakter dizisi gibi sadece bir amaç için :-)
TMG

1
Peki ya python3?
RicardoE

@RicardoE bu cevabı kontrol et .
Pablo A,

27

kabuk

Aşağıdaki komut satırını deneyin:

$ echo "%C3%A6ndr%C3%BCk" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
ændrük

Bunu takma ad olarak tanımlayabilir ve kabuk rc dosyalarınıza ekleyebilirsiniz :

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

Sonra her ihtiyacın olduğunda, sadece git:

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

darbe

Komut dosyası yazarken aşağıdaki sözdizimini kullanabilirsiniz:

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

Ancak yukarıdaki sözdizimi pluses ( +) işlevini doğru işlemez , bu nedenle onları boşluklarla değiştirmelisiniz sed.

Aşağıdakileri urlencode()ve urldecode()işlevleri de kullanabilirsiniz :

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

Urldecode () verilerinin ters eğik çizgi içermediğini varsaydığını unutmayın.


bash + xxd

xxdAracı ile Bash işlevi :

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
}

Bulundu cdown en özü dosyası ayrıca, stackoverflow .


piton

Aşağıdaki takma adları tanımlamayı deneyin:

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

Kullanımı:

$ urlencode "ændrük"
C%26ndrC%3Ck
$ urldecode "%C3%A6ndr%C3%BCk"
ændrük

Kaynak: ruslanspivak


PHP

PHP kullanarak aşağıdaki komutu deneyebilirsiniz:

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

ya da sadece:

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

-RÇoklu hat girişi için kullanın .


Perl

Perl'de kullanabilirsiniz URI::Escape.

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

Veya bir dosyayı işlemek için:

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

sed

Kullanarak sedelde edilebilir:

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

awk

Deneyin anon çözüm:

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

Bakınız: Metnin kodunu değiştirmek için awk printf kullanımı .


dosya adlarını çözme

URL kodlamasını dosya adlarından kaldırmanız gerekirse deurlname, renameutils(örneğin deurlname *.*) aracını kullanın .

Ayrıca bakınız:


İlgili:


Bash + XXD sürümü ihtiva dizeleri ile çalışmaz %, belki yerini alabilir printf "$c"ile printf "%c" "$c"? Başka bir sorun da bazı ASCII olmayan karakterlerin äbazı dil ayarlarında kodlanmadığı (örneğin ), belki bir export LC_ALL=Cişlev ekleyebilmesidir (işlev dışında hiçbir şeyi etkilememesi gereken)?
12431234123412341234123

8

Yüzde-kodlu ayrılmış URI karakterleri ve ASCII olmayan karakterler

jq -s -R -r @uri

-s( --slurp) giriş satırlarını bir diziye okur ve -s -R( --slurp --raw-input) girişi tek bir dizeye okur. -r( --raw-output), JSON string değişmezleri yerine dizelerin içeriğini çıkarır.

Tüm karakterleri yüzde olarak kodlama

xxd -p|tr -d \\n|sed 's/../%&/g'

tr -d \\nxxd -pHer 60 karakterden sonra eklenen satır beslemelerini kaldırır .

Yüzde ASCII alfasayısal karakterler dışındaki tüm karakterleri kodlama

eu () {
    local LC_ALL=C c
    while IFS= read -r -n1 -d '' c
    do 
        if [[ $c = [[:alnum:]] ]]
        then 
            printf %s "$c"
        else
            printf %%%02x "'$c"
        fi
    done
}

-d ''Bu olmadan satır beslemeleri ve boş baytlar atlanırdı. Without IFS=bu karakterleri yerini alacak IFSolan %00. Without LC_ALL=CBu örnek için yerini alacak olan %3042UTF-8 yerel ayarda.


5

Yalnızca kod çözme için saf bash çözümü :

$ a='%C3%A6ndr%C3%BCk'
$ echo -e "${a//%/\\x}"
ændrük

4

Bu konudaki en iyi cevap hakkında yorum yapamam , bu yüzden işte benim.

Şahsen bu takma adları URL kodlama ve kod çözme için kullanırım:

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

Her iki komut da verileri dönüştürmenize, komut satırı argümanı olarak geçirmenize veya standart girdiden okumanıza olanak tanır , çünkü her iki tek gömlek komut satırı argümanları olup olmadığını kontrol eder (hatta boş olanları) ve bunları işler veya yalnızca standart girişi okur.

güncelleme 2015-07-16 (boş 1. arg)

... muru yorumuna göre.

2017-05-28 güncellemesi (eğik çizgi kodlaması)

Eğer eğik çizgiyi de kodlamanız gerekiyorsa, sadece teklif fonksiyonuna boş bir ikinci argüman ekleyin, o zaman eğik çizgi de kodlanacaktır.

Yani, son olarak urlencode takma içinde bash böyle görünüyor:

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

Örnek

$ 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
Bence sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]daha uygun olabilir. Özellikle bunu komut dosyalarında kullanırsanız ve yanlışlıkla boş bir ilk argüman verirseniz.
muru

@Muru yorumuna göre, komut satırındaki bir argüman için kontrolü değiştirdim. Öyleydi: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Şimdi: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] Boş bir ilk argüman bile varsa, komut standart girdiden giriş beklemiyor, ancak boş bir argüman işliyor.
DIG mbl

2

"Yüzde kodlanmış" karakterleri içeren bir dosyayı yeniden adlandırabilen renameutilsyardımcı programı içeren bir paket buldum deurlname.

Ne yazık ki, stdin veya bir komut satırı seçeneğinin kodunu çözmez, ancak yalnızca bir dosyayı yeniden adlandırır, bu nedenle kod çözmeyi elde etmek için sahte bir dosya oluşturmanız gerekir (yeniden adlandırılmış dosyanın adı), ancak bazı bash komut dosyasıyla işlem otomatikleştirilebilir .

Hangi karakterlerin kodlanacağı sorgulanabilir olsa bile kodlama kısmı hakkında bilgi yoktur. Sadece ASCII olmayan?

Daha iyi bir araç / yöntem olması gerektiğini düşünüyorum.


1

Stefano ansqer'a benzer ancak Python 3'te:

python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" æ
python -c "import urllib.parse, sys; print(urllib.parse.unquote(sys.argv[1]))" %C3%A6

Ayrıca eğik çizgi kodlamak için:

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

Buradaki fark hakkında daha fazla bilgi .


0

İşte kodlama için bir POSIX Awk işlevi:

function encodeURIComponent(str, j, q) {
  while (y++ < 125) z[sprintf("%c", y)] = y
  while (y = substr(str, ++j, 1))
    q = y ~ /[[:alnum:]_.!~*\47()-]/ ? q y : q sprintf("%%%02X", z[y])
  return q
}

Örnek

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.