ไทย

เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ · URL ตัวเข้ารหัสและตัวถอดรหัส

วิธีการทำงานของการเข้ารหัสเปอร์เซ็นต์: จากอักขระไปจนถึงลำดับ UTF-8 ไบต์ไปจนถึงลำดับ %XX

· มันทำงานอย่างไร

การเข้ารหัส URL utf-8 การเข้ารหัสเปอร์เซ็นต์ นักพัฒนา

รหัสอักขระที่แมปผ่านขั้นตอนการเข้ารหัส UTF-8 ลงในลำดับเลขฐานสิบหกที่เข้ารหัสเปอร์เซ็นต์
ภาพประกอบเวกเตอร์ต้นฉบับ ToolAcre

การเข้ารหัสเปอร์เซ็นต์ไม่เข้ารหัสอักขระ มันเข้ารหัสไบต์ โพสต์นี้แสดงให้เห็นว่าอักขระกลายเป็น UTF-8 ไบต์ได้อย่างไร จากนั้นจึงเป็นคู่เลขฐานสิบหก และเหตุใดตัวอักษรที่มีการเน้นเสียงจึงใช้ %XX สองกลุ่ม ในขณะที่อีโมจิใช้เวลาสี่กลุ่ม

เหตุใด 'é' จึงกลายเป็น %C3%A9 แทนที่จะเป็น %E9 - การสังเกตที่เผยให้เห็นเลเยอร์ไบต์ที่อยู่ด้านล่าง

เมื่อนักพัฒนารุ่นน้องเห็น %C3%A9 ใน URL การเข้ารหัสเปอร์เซ็นต์จะทำงานเป็นไบต์ ไม่ใช่อักขระ อักขระ é ไม่ใช่หนึ่งไบต์ UTF-8 เข้ารหัสเป็นสอง: C3 A9 กฎการเข้ารหัสเปอร์เซ็นต์จาก RFC 3986 นั้นง่ายมาก: เข้ารหัสแต่ละไบต์เป็นเครื่องหมายเปอร์เซ็นต์ตามด้วยเลขฐานสิบหกสองหลัก ความแตกต่างนั้นเปลี่ยนคำอธิบายจากลึกลับไปสู่ตรรกะ

การทำความเข้าใจการเข้ารหัสเปอร์เซ็นต์ต้องอาศัยความเข้าใจ UTF-8 ข้อความต้องถูกแปลงเป็นไบต์โดยใช้การเข้ารหัสอักขระ UTF-8 เป็นมาตรฐานสำหรับ URL และเว็บ แสดงอักขระเป็นลำดับไบต์ที่มีความยาวผันแปรได้: ASCII ใช้หนึ่งไบต์ ตัวอักษรเน้นเสียงใช้สอง อีโมจิใช้สี่ แต่ละขั้นตอนมีความแตกต่างกัน: อักขระ, จุดโค้ด Unicode, UTF-8 ไบต์ จากนั้นจึงจับคู่ %XX การข้ามไปที่เลขฐานสิบหกโดยไม่เข้าใจไบต์จะพลาดประเด็น

กฎการเข้ารหัสเปอร์เซ็นต์จาก RFC 3986 — หนึ่ง % ตามด้วยเลขฐานสิบหกสองหลักต่อไบต์ แนะนำให้ใช้ตัวพิมพ์ใหญ่

RFC 3986 กำหนดหนึ่งกฎ: เข้ารหัสแต่ละไบต์เป็นเปอร์เซ็นต์ตามด้วยเลขฐานสิบหกตัวพิมพ์ใหญ่สองตัว อักขระที่ไม่ได้สงวนไว้ซึ่งไม่จำเป็นต้องเข้ารหัส ได้แก่ ตัวอักษร ตัวเลข ยัติภังค์ ขีดล่าง จุด และเครื่องหมายทิลเดอ ทุกอย่างอื่นจะต้องได้รับการเข้ารหัส ช่องว่างกลายเป็น %20 เครื่องหมายทับกลายเป็น %2F และเครื่องหมายเปอร์เซ็นต์จะกลายเป็น %25 สิ่งนี้จะป้องกันไม่ให้อักขระพิเศษในค่าการสืบค้นทำลายโครงสร้าง URL

ช่องว่างเข้ารหัสเป็นไบต์ 0x20 กลายเป็น %20 เครื่องหมายทับคือ 0x2F กลายเป็น %2F เหล่านี้คือ ASCII อักขระที่ต้องการหนึ่งไบต์ ตัวอักษรเน้นเสียงและอีโมจิแตกต่างกัน เครื่องหมายเปอร์เซ็นต์กลายเป็น %25 ตัวคั่นที่สงวนไว้เช่นโคลอนจะถูกเข้ารหัสเพื่อรักษาโครงสร้าง วิธีนี้จะป้องกันไม่ให้เครื่องหมายแอมเพอร์แซนด์แบบฝังหรือเท่ากับในพารามิเตอร์คิวรีแยกวิเคราะห์ แต่ละไบต์จะกลายเป็น %HH

UTF-8 เป็นชุดอักขระที่สันนิษฐาน - เหตุใด URL สมัยใหม่จึงเป็น UTF-8 และที่ที่มีข้อยกเว้นแบบเดิม

UTF-8 ใช้การเข้ารหัสที่มีความยาวผันแปรได้ ASCII จากจุดรหัส 0 ถึง 127 คือหนึ่งไบต์ อักขระตั้งแต่ 128 ถึง 2047 รวมถึงตัวอักษรละตินที่มีการเน้นเสียง มีขนาด 2 ไบต์ อักขระตั้งแต่ 2048 ถึง 65535 ซึ่งพบได้ทั่วไปในสคริปต์เอเชียตะวันออก จะมีขนาด 3 ไบต์ อักขระที่อยู่เหนือ 65535 รวมถึงอิโมจิส่วนใหญ่มีขนาดสี่ไบต์ แต่ละไบต์จะถูกนำหน้าด้วยบิตที่ส่งสัญญาณว่ามีไบต์ตามมากี่ไบต์

ตัวอักษรเน้นเสียง é คือรหัส Unicode จุด U+00E9 UTF-8 เข้ารหัสเป็นสองไบต์: 0xC3 และ 0xA9 การเข้ารหัสเปอร์เซ็นต์จะสร้าง %C3%A9 ภาษาเยอรมัน ü (U+00FC) เข้ารหัสเป็น 0xC3 0xBC กลายเป็น %C3%BC ภาษาสเปน ñ (U+00F1) เข้ารหัสเป็น 0xC3 0xB1 กลายเป็น %C3%B1 รูปแบบมีความสอดคล้องกัน: ไบต์แรกส่งสัญญาณลำดับสองไบต์ ตัวอักษรเน้นเสียงหนึ่งตัวจะขยายด้วยอักขระหกตัวในการเข้ารหัส

ตัวอย่างการทำงาน: การเข้ารหัส 'cafe 😀' ไบต์ต่อไบต์ - จุดโค้ด, UTF-8 ไบต์ และสตริงผลลัพธ์

อิโมจิทำให้เลเยอร์ไบต์ชัดเจน อิโมจิยกนิ้ว 👍 คือรหัสจุด U+1F44D UTF-8 เข้ารหัสเป็นสี่ไบต์: F0 9F 91 8D การเข้ารหัสเปอร์เซ็นต์จะสร้าง %F0%9F%918D: อักขระ 12 ตัวสำหรับหนึ่งสัญลักษณ์ สไมลี่ 😀 (U+1F600) เข้ารหัสเป็น F0 9F 98 80 กลายเป็น %F0%9F%9880 ลำดับสี่ไบต์กลายเป็นอักขระที่เข้ารหัสสิบสองเปอร์เซ็นต์

ข้อความผสมแสดงให้เห็นว่าเหตุใดการทำความเข้าใจไบต์จึงมีความสำคัญ วลี "cafe 😀" ประกอบด้วย ASCII ธรรมดา สำเนียง และอีโมจิ ตัวอักษร c, a, f เข้ารหัสเป็น 63, 61, 66 é เข้ารหัสเป็น C3 A9 ช่องว่างเข้ารหัสเป็น 20 อีโมจิเข้ารหัสเป็น F0 9F 98 80 ผลลัพธ์คือ "caf%C3%A9%20%F0%9F%9880" การทำความเข้าใจว่าไบต์ใดที่จำเป็นต้องเข้ารหัสทำให้สามารถคาดเดาเอาต์พุตได้

ถอดรหัสแบบย้อนกลับ - รวบรวม %XX กลุ่มเป็นไบต์แล้วตีความว่าเป็น UTF-8

การถอดรหัสจะทำให้กระบวนการย้อนกลับ ตัวถอดรหัสจะสแกนหาคู่ %XX และรวบรวมเป็นค่าไบต์ เมื่อเห็น %C3%A9 มันจะแยกไบต์ C3 และ A9 UTF-8 การถอดรหัสตีความสิ่งเหล่านั้นเป็นอักขระ é หากลำดับไม่สมบูรณ์ เช่น %C3 เพียงอย่างเดียว ผลลัพธ์จะเป็นข้อผิดพลาด ตัวถอดรหัสรู้จากบิตนำหน้า UTF-8 ว่า C3 ต้องใช้ไบต์ที่สอง

ตัวพิมพ์ไม่สำคัญในเลขฐานสิบหก %C3%A9 และ %c3%a9 ถอดรหัสเหมือนกัน RFC อนุญาตให้ใช้ตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก แต่ควรใช้ตัวพิมพ์ใหญ่ แต่ตัวพิมพ์สำคัญสำหรับอักขระ: é (ตาม %C3%A9) ไม่เหมือนกับ É (ตาม %C3%89) การเปรียบเทียบ URL จะต้องทำให้การเข้ารหัสเปอร์เซ็นต์เป็นมาตรฐาน หรือเสี่ยงต่อการปฏิบัติต่อทรัพยากรที่เหมือนกันว่าต่างกัน เฟรมเวิร์กทำให้เป็นมาตรฐานก่อนการแคช

เหตุใดตัวพิมพ์จึงไม่สำคัญในเลขฐานสิบหก แต่มีความสำคัญที่อื่น - กฎการทำให้เป็นมาตรฐานและการเปรียบเทียบ URL

RFC 3986 กล่าวถึง punycode สำหรับชื่อโดเมนและการเข้ารหัสแบบฟอร์มสำหรับการส่งเป็นกฎแยกต่างหาก Punycode เข้ารหัสชื่อโดเมนที่ไม่ใช่ ASCII โดยไม่มีเครื่องหมายเปอร์เซ็นต์สำหรับความเข้ากันได้ DNS โดเมน 😀.example กลายเป็น "xn--js8h.example" การเข้ารหัสแบบฟอร์มจะแก้ไขการเข้ารหัสเปอร์เซ็นต์โดยมีข้อยกเว้นหนึ่งข้อ: การเว้นวรรคจะกลายเป็นเครื่องหมายบวกแทน %20 ส่งแบบฟอร์มเป็น application/x-www-form-urlencoded ใช้เครื่องหมายบวกเพื่อเว้นวรรค

เครื่องมือเข้ารหัส URL แสดงทั้งสามโหมด: การเข้ารหัสส่วนประกอบ การเข้ารหัส URL ทั้งหมด และการเข้ารหัสแบบฟอร์ม การเข้ารหัสส่วนประกอบด้วย encodeURIComponent เข้ารหัสอักขระพิเศษทุกตัวรวมถึงตัวคั่น เหมาะสำหรับค่าการสืบค้น การเข้ารหัสทั้ง URL ด้วย encodeURI จะรักษาอักขระโครงสร้างสำหรับ URL ที่สมบูรณ์ การเข้ารหัสแบบฟอร์มมีไว้สำหรับเนื้อหา POST แต่ละคนใช้ UTF-8; ต่างกันแค่ว่าไบต์ใดที่ถูกปล่อยทิ้งไว้โดยไม่มีการเข้ารหัส

Punycode และการเข้ารหัสแบบฟอร์ม: มาตรฐานพี่น้อง ไม่ใช่ส่วนขยายการเข้ารหัสเปอร์เซ็นต์

เปอร์สเปคทีฟไบต์ช่วยแก้ไข URL ความลึกลับ ทำไมอีโมจิหนึ่งตัวต้องมีอักขระสิบสองตัว? เนื่องจาก UTF-8 ใช้สี่ไบต์ แต่ละไบต์จะกลายเป็น %HH เหตุใด URL บางรายการจึงมี %2F สำหรับเครื่องหมายทับ ในขณะที่บาง URL จึงมีเครื่องหมายทับธรรมดา เนื่องจากโหมดการเข้ารหัสเป็นตัวกำหนด: เครื่องหมายทับในส่วนของเส้นทางจะยังคงไม่มีการเข้ารหัส แต่ภายในค่าการค้นหานั้น จะต้องเป็น %2F เพื่อหลีกเลี่ยงการอ่านผิด

คิดเป็นไบต์สำหรับการเข้ารหัสเปอร์เซ็นต์ที่คาดเดาได้ อักขระเป็นจุดโค้ด Unicode UTF-8 คือการแสดงไบต์ การเข้ารหัสเปอร์เซ็นต์คือรูปแบบการส่งข้อมูล การขยายอักขระเกิดขึ้นที่เลเยอร์ UTF-8 ตัวพิมพ์ฐานสิบหกไม่ส่งผลต่อการถอดรหัส แต่ตัวพิมพ์มีผลกระทบ ลำดับไบต์ที่ไม่ถูกต้องล้มเหลวที่ UTF-8 เนื่องจากกฎคำนำหน้าที่เข้มงวด เครื่องมือเข้ารหัส URL แสดงความก้าวหน้านี้

ประเด็นสำคัญ: คิดเป็นไบต์ — วิธีที่ตัวเข้ารหัสและตัวถอดรหัส URL แสดงเอาต์พุต %XX ที่แน่นอนสำหรับข้อความใดๆ ที่คุณวางในเบราว์เซอร์

ตัวอย่างการทำงาน: การเข้ารหัส "cafe 😀" คำว่า คาเฟ่ มีตัวอักษร c, a, f เป็น ASCII ไบต์เดี่ยว: 63, 61, 66 é คือ UTF-8 สองไบต์: C3 A9 พื้นที่คือ 20 อิโมจิ 😀 คือสี่ไบต์: F0 9F 98 80 ตัวอักษร ASCII ที่ไม่ได้สงวนไว้ยังคงมองเห็นได้ ผลลัพธ์: "caf%C3%A9%20%F0%9F%9880" นี่แสดงให้เห็นว่าเหตุใดอีโมจิหนึ่งตัวจึงขยายเป็นสิบสองตัวอักขระ

ประเด็นสำคัญ: คิดเป็นไบต์ ไม่ใช่ตัวอักษร การเข้ารหัสเปอร์เซ็นต์จะมีผลหลังจากการเข้ารหัส UTF-8 แต่ละไบต์จะกลายเป็น %HH ความยาวผันแปรได้ UTF-8 หมายถึงอักขระจะขยายแตกต่างกัน: ASCII กลายเป็น %XX (ตัวอักษรสองตัว) การเน้นเสียงแบบสองไบต์จะกลายเป็น %XX%XX (หกตัวอักษร) อีโมจิสี่ไบต์กลายเป็น %XX%XX%XX%XX (สิบสองตัวอักษร) วางข้อความลงในเครื่องมือเข้ารหัส URL และสังเกตความคืบหน้า