Làm cách nào tôi có thể mã hóa và giải mã các chuỗi được mã hóa phần trăm trên dòng lệnh?


31

Làm cách nào tôi có thể mã hóa và giải mã các chuỗi được mã hóa phần trăm (được mã hóa URL) trên dòng lệnh?

Tôi đang tìm kiếm một giải pháp có thể làm điều này:

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

Bạn có muốn kết hợp các bảng mã khác nhau không? %E6ndr%FCkkhông giống như (tiêu chuẩn) UTF8 đối với tôi. Hay đó chỉ là một ví dụ?
sắp xếp

@arrange Cảm ơn bạn đã nắm bắt điều đó. Rõ ràng tôi đã chọn quả táo xấu trong số các kết quả tìm kiếm cho các trình chuyển đổi trực tuyến.
ændrük

Để biết tên tệp, hãy xem: Cách xóa mã hóa URI trong tên tệp .
kenorb

Câu trả lời:


35

Các lệnh này làm những gì bạn muốn:

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

Nếu bạn muốn mã hóa không gian như +, thay thế urllib.quotebằng urllib.quote_plus.

Tôi đoán bạn sẽ muốn bí danh họ ;-)


1
Æ ký tự ở cuối dòng đầu tiên là gì? Chỉnh sửa: tự trả lời - hiểu rồi, đó chỉ là một chuỗi ký tự UTF8 được mã hóa cho mục đích ví dụ :-)
TMG

1
python3 thì sao?
RicardoE

@RicardoE kiểm tra câu trả lời này .
Pablo A

27

vỏ

Hãy thử dòng lệnh sau:

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

Bạn có thể định nghĩa nó là bí danh và thêm nó vào các tệp RC shell của bạn :

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

Sau đó, mỗi khi bạn cần, chỉ cần đi với:

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

bash

Khi viết kịch bản, bạn có thể sử dụng cú pháp sau:

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

Tuy nhiên, cú pháp trên sẽ không xử lý +chính xác dấu cộng ( ), vì vậy bạn phải thay thế chúng bằng dấu cách sed.

Bạn cũng có thể sử dụng các chức năng urlencode()urldecode()chức năng sau:

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

Lưu ý rằng urldecode () của bạn giả sử dữ liệu không chứa dấu gạch chéo ngược.


bash + xxd

Hàm Bash với xxdcông cụ:

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
}

Tìm thấy trong tập tin chính của cdown , cũng tại stackoverflow .


Con trăn

Cố gắng xác định các bí danh sau:

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

Sử dụng:

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

Nguồn: ruslanspivak


PHP

Sử dụng PHP bạn có thể thử lệnh sau:

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

hoặc chỉ:

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

Sử dụng -Rcho đầu vào nhiều dòng.


Perl

Trong Perl bạn có thể sử dụng URI::Escape.

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

Hoặc để xử lý tệp:

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

quyến rũ

Sử dụng sedcó thể đạt được bằng cách:

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

ôi

Hãy thử giải pháp anon :

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

Xem: Sử dụng awk printf để văn bản urldecode .


giải mã tên tập tin

Nếu bạn cần xóa mã hóa url khỏi tên tệp, hãy sử dụng deurlnamecông cụ từ renameutils(ví dụ deurlname *.*).

Xem thêm:


Liên quan:


Phiên bản bash + xxd không hoạt động với các chuỗi có chứa a %, có lẽ bạn có thể thay thế printf "$c"bằng printf "%c" "$c"? Một vấn đề khác là một số trình duyệt không phải ASCII không được mã hóa (chẳng hạn như ä) trong một số cài đặt ngôn ngữ, có thể thêm một export LC_ALL=Cchức năng (không nên ảnh hưởng đến bất cứ điều gì bên ngoài chức năng)?
12431234123412341234123

8

Các ký tự URI dành riêng phần trăm được mã hóa và các ký tự không phải ASCII

jq -s -R -r @uri

-s( --slurp) đọc các dòng đầu vào thành một mảng và -s -R( --slurp --raw-input) đọc đầu vào thành một chuỗi. -r( --raw-output) xuất nội dung của chuỗi thay vì bằng chuỗi ký tự JSON.

Phần trăm mã hóa tất cả các ký tự

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

tr -d \\nxóa các nguồn cấp dữ liệu được thêm vào xxd -psau mỗi 60 ký tự.

Phần trăm mã hóa tất cả các ký tự trừ các ký tự chữ và số ASCII trong Bash

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
}

Nếu không có -d ''điều này sẽ bỏ qua các nguồn cấp dữ liệu và byte rỗng. Nếu không có IFS=điều này sẽ thay thế các nhân vật trong IFSvới %00. Nếu không có LC_ALL=Cđiều này, ví dụ sẽ thay thế bằng %3042ngôn ngữ UTF-8.


5

Giải pháp bash tinh khiết chỉ để giải mã :

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

4

Tôi không thể nhận xét về câu trả lời tốt nhất trong chủ đề này , vì vậy đây là của tôi.

Cá nhân, tôi sử dụng các bí danh này để mã hóa và giải mã 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])"'

Cả hai lệnh đều cho phép bạn chuyển đổi dữ liệu, được truyền dưới dạng đối số dòng lệnh hoặc đọc nó từ đầu vào tiêu chuẩn , bởi vì cả hai dòng đều kiểm tra xem có đối số dòng lệnh (thậm chí là trống) và xử lý chúng hay chỉ đọc đầu vào tiêu chuẩn.

cập nhật 2015-07-16 (đối số 1 trống)

... theo nhận xét của @muru.

cập nhật 2017-05-28 (mã hóa gạch chéo)

Nếu bạn cũng cần mã hóa dấu gạch chéo, chỉ cần thêm một đối số thứ hai trống vào hàm trích dẫn, thì dấu gạch chéo cũng sẽ được mã hóa.

Vì vậy, cuối cùng urlencode bí danh trong bash trông như thế này:

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

Thí dụ

$ 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
Tôi nghĩ sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]có thể phù hợp hơn. Đặc biệt là nếu bạn sử dụng điều này trong các kịch bản và vô tình đưa ra một đối số đầu tiên trống rỗng.
muru

Theo nhận xét của @muru, tôi đã thay đổi việc kiểm tra đối số trên dòng lệnh. Đó là: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Bây giờ: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] Nghĩa là, nếu thậm chí còn có một đối số trống đầu tiên, lệnh không chờ đầu vào từ đầu vào tiêu chuẩn, mà xử lý một đối số trống.
DIG MBL

2

Tôi đã tìm thấy một gói, renameutilscó chứa tiện ích deurlnamecó thể đổi tên một tệp chứa các ký tự "được mã hóa phần trăm".

Thật không may, nó không giải mã stdin hoặc tùy chọn dòng lệnh, mà chỉ đổi tên một tệp, vì vậy bạn phải tạo một tệp giả để có được giải mã (tên của tệp được đổi tên), nhưng với một số kịch bản bash có thể được tự động hóa .

Không có thông tin về phần mã hóa, thậm chí có thể nghi ngờ mã hóa ký tự nào. Chỉ không ASCII?

Tôi nghĩ nên có một số công cụ / phương pháp tốt hơn.


1

Tương tự như Stefano ansqer nhưng trong Python 3:

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

Để mã hóa cũng gạch chéo:

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

Thông tin thêm về sự khác biệt ở đây .


0

Đây là chức năng POSIX Awk để mã hóa:

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
}

Thí dụ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.