ฉันจะเข้ารหัสและถอดรหัสสตริงที่เข้ารหัสเปอร์เซ็นต์ในบรรทัดคำสั่งได้อย่างไร


31

ฉันจะเข้ารหัสและถอดรหัสสตริงที่เข้ารหัสเปอร์เซ็นต์ (เข้ารหัส URL) บนบรรทัดคำสั่งได้อย่างไร

ฉันกำลังมองหาโซลูชันที่สามารถทำได้:

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

คุณต้องการรวมการเข้ารหัสที่แตกต่างกันด้วยหรือไม่? %E6ndr%FCkดูไม่เหมือน (มาตรฐาน) UTF8 สำหรับฉัน หรือเป็นเพียงตัวอย่าง?
จัด

@ จัดขอบคุณสำหรับการจับที่ เห็นได้ชัดว่าฉันเลือกแอปเปิ้ลที่ไม่ดีในผลการค้นหาสำหรับผู้แปลงออนไลน์
ændrük

สำหรับชื่อไฟล์โปรดดูที่: วิธีการลบ URI เข้ารหัสในชื่อไฟล์
kenorb

คำตอบ:


35

คำสั่งเหล่านี้ทำสิ่งที่คุณต้องการ:

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

หากคุณต้องการพื้นที่เข้ารหัสเป็น+แทนที่ด้วยurllib.quoteurllib.quote_plus

ฉันคาดเดาว่าคุณจะต้องการนามแฝงพวกเขา ;-)


1
อักขระæที่ท้ายบรรทัดแรกคืออะไร แก้ไข: ตอบคำถามกับตัวเอง - เข้าใจแล้วมันเป็นเพียงอักขระตัวเดียว UTF8 ที่ต้องเข้ารหัสสตริงเพื่อจุดประสงค์ตัวอย่าง :-)
TMG

1
แล้ว python3 ล่ะ?
RicardoE

@RicardoE ตรวจสอบคำตอบนี้
Pablo

27

เปลือก

ลองใช้บรรทัดคำสั่งต่อไปนี้:

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

คุณอาจกำหนดเป็นนามแฝงและเพิ่มลงในไฟล์shell rcของคุณ:

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

จากนั้นทุกครั้งที่คุณต้องการเพียงแค่ไปกับ:

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

ทุบตี

เมื่อสคริปต์คุณสามารถใช้ไวยากรณ์ต่อไปนี้:

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

ไวยากรณ์ แต่ข้างต้นจะได้จัดการ pluses ( +) sedอย่างถูกต้องเพื่อให้คุณได้เพื่อแทนที่พวกเขามีช่องว่างทาง

คุณยังสามารถใช้ฟังก์ชั่นurlencode()และ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}"
}

โปรดทราบว่า urldecode ของคุณ () ถือว่าข้อมูลไม่มีเครื่องหมายแบ็กสแลช


bash + xxd

ฟังก์ชั่นทุบตีด้วย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
}

พบในไฟล์เค้า cdown ของยังที่StackOverflow


หลาม

พยายามกำหนดนามแฝงต่อไปนี้:

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

การใช้งาน:

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

ที่มา: ruslanspivak


PHP

ใช้ PHP คุณสามารถลองคำสั่งต่อไปนี้:

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

หรือเพียงแค่:

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

ใช้-Rสำหรับอินพุตหลายบรรทัด


Perl

ใน Perl URI::Escapeคุณสามารถใช้

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

หรือเพื่อประมวลผลไฟล์:

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

sed

การใช้sedสามารถทำได้โดย:

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

awk

ลองใช้วิธีแก้ปัญหาไม่ช้า :

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

ดู: การใช้ printf awk กับข้อความ


การถอดรหัสชื่อไฟล์

หากคุณต้องการลบการเข้ารหัส URL ออกจากชื่อไฟล์ให้ใช้deurlnameเครื่องมือจากrenameutils(เช่นdeurlname *.*)

ดูสิ่งนี้ด้วย:


ที่เกี่ยวข้อง:


รุ่น bash + xxd ไม่สามารถใช้งานกับสตริงที่มี a %, บางทีคุณสามารถแทนที่printf "$c"ด้วยprintf "%c" "$c"? ปัญหาอีกข้อหนึ่งคือตัวอักษรที่ไม่ใช่ ASCII บางตัวไม่ได้เข้ารหัส (เช่นä) ในการตั้งค่าภาษาบางอย่างอาจเพิ่ม a export LC_ALL=Cในฟังก์ชั่น (ซึ่งจะไม่ส่งผลกระทบต่อสิ่งอื่นนอกฟังก์ชั่น)
12431234123412341234123

8

อักขระ URI ที่สงวนไว้เป็นเปอร์เซ็นต์เข้ารหัสและอักขระที่ไม่ใช่ ASCII

jq -s -R -r @uri

-s( --slurp) อ่านบรรทัดอินพุตเข้าในอาร์เรย์และ-s -R( --slurp --raw-input) อ่านอินพุตเป็นสตริงเดียว -r( --raw-output) แสดงผลเนื้อหาของสตริงแทนตัวอักษรของสตริง JSON

เปอร์เซ็นต์เข้ารหัสอักขระทั้งหมด

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

tr -d \\nลบ linefeeds ที่เพิ่มโดยxxd -pหลังจากทุก ๆ 60 ตัวอักษร

การเข้ารหัสเปอร์เซ็นต์อักขระทั้งหมดยกเว้นอักขระตัวอักษรและตัวเลข ASCII ใน 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
}

หากไม่มี-d ''สิ่งนี้จะข้าม linefeeds และ null null โดยไม่ต้องIFS=นี้จะเข้ามาแทนที่ตัวอักษรในด้วยIFS %00หากไม่มีLC_ALL=Cสิ่งนี้จะเป็นการแทนที่ด้วย%3042ในโลแคล UTF-8


5

Pure bash solution สำหรับการถอดรหัสเท่านั้น :

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

4

ฉันไม่สามารถแสดงความคิดเห็นกับคำตอบที่ดีที่สุดในหัวข้อนี้ดังนั้นนี่คือของฉัน

ส่วนตัวผมใช้นามแฝงเหล่านี้เพื่อการเข้ารหัสและถอดรหัส 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])"'

ทั้งสองคำสั่งอนุญาตให้คุณแปลงข้อมูลส่งผ่านเป็นอาร์กิวเมนต์บรรทัดคำสั่งหรืออ่านจากอินพุตมาตรฐานเนื่องจากทั้งสอง liners ตรวจสอบว่ามีอาร์กิวเมนต์บรรทัดคำสั่ง (แม้แต่ที่ว่างเปล่า) และประมวลผลพวกเขาหรือเพียงแค่อ่านอินพุตมาตรฐานมิฉะนั้น

อัปเดต 2015-07-16 (ว่าง ARG 1)

... ตามความคิดเห็น @muru

อัพเดท 2017-05-28 (การเข้ารหัสสแลช)

หากคุณต้องการเข้ารหัสสแลชให้เพิ่มอาร์กิวเมนต์ที่สองที่ว่างในฟังก์ชันอัญประกาศจากนั้นสแลชจะถูกเข้ารหัส

ดังนั้นในที่สุดurlencode นามแฝงในbashจะมีลักษณะเช่นนี้:

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

ตัวอย่าง

$ 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
ฉันคิดว่าsys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]อาจเหมาะสมกว่า โดยเฉพาะอย่างยิ่งถ้าคุณใช้สิ่งนี้ในสคริปต์และตั้งใจให้อาร์กิวเมนต์แรกที่ว่างเปล่า
muru

ตามความคิดเห็นของ @muru ฉันเปลี่ยนการตรวจสอบหาอาร์กิวเมนต์บนบรรทัดคำสั่ง มันเป็น: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] ตอนนี้: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] นั่นคือถ้ามีก็เป็นอาร์กิวเมนต์แรกที่ว่างเปล่าคำสั่งไม่รอสำหรับการป้อนข้อมูลจากอินพุตมาตรฐาน แต่กระบวนการโต้แย้งที่ว่างเปล่า
DIG mbl

2

ฉันพบแพ็คเกจrenameutilsที่มียูทิลิตี้deurlnameที่สามารถเปลี่ยนชื่อไฟล์ที่มีอักขระ "เข้ารหัสร้อยละ"

น่าเสียดายที่มันไม่ได้ถอดรหัส stdin หรือตัวเลือกบรรทัดคำสั่ง แต่เพียงเปลี่ยนชื่อไฟล์ดังนั้นคุณต้องสร้างไฟล์ดัมมี่เพื่อรับการถอดรหัส (ชื่อของไฟล์ที่เปลี่ยนชื่อ) แต่ด้วย bash script บางกระบวนการสามารถเป็นแบบอัตโนมัติได้ .

ไม่มีข้อมูลเกี่ยวกับส่วนการเข้ารหัสแม้ว่าอาจเป็นปัญหาว่าอักขระตัวใดที่จะเข้ารหัส ไม่ใช่ ASCII เท่านั้นหรือ

ฉันคิดว่าควรมีเครื่องมือ / วิธีที่ดีกว่า


1

แอพที่คล้ายกับStefano ansqerแต่ใน 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

ในการเข้ารหัสทับ:

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

ข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างที่นี่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.