ไทย

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

การขยายฐาน Base64 อธิบาย: เครื่องหมาย = หมายถึงอะไร และเมื่อใดจึงจำเป็น

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

base64 การเข้ารหัส นักพัฒนาเวิร์กโฟลว์

เอาต์พุต Base64 แสดงบล็อกเสริมและเครื่องหมายเท่ากับ
ภาพประกอบเวกเตอร์ต้นฉบับ ToolAcre

= ที่ส่วนท้ายของสตริง Base64 ไม่ใช่การตกแต่ง แต่จะบันทึกจำนวนไบต์ที่กลุ่มสุดท้ายสั้น โพสต์นี้จะอธิบายเลขคณิต เหตุใดบางสตริงจึงไม่มี และเหตุใดผู้ถอดรหัสจึงไม่เห็นด้วยกับการขาดช่องว่างภายใน

ข้อยกเว้น 'ช่องว่างภายในที่ไม่ถูกต้อง' จากโทเค็นที่ดูดี — การถอดรหัสที่ล้มเหลวและมีอักขระหายไปหนึ่งหรือสองตัวที่อยู่ด้านหลัง

เมื่อตัวถอดรหัส Base64 รายงานช่องว่างภายในที่ไม่ถูกต้อง สตริงดูสมบูรณ์ แต่มีข้อผิดพลาดทางโครงสร้าง เครื่องหมายเท่ากับนั้นไม่ใช่เรื่องสวยงาม แต่ละอันจะเข้ารหัสจำนวนไบต์ที่กลุ่มสุดท้ายนั้นสั้น ช่วยให้ตัวถอดรหัสรู้ได้อย่างแน่ชัดว่าข้อมูลจริงสิ้นสุดลงเมื่อใด การทำความเข้าใจเครื่องหมาย = เหล่านั้น และเหตุใดตัวถอดรหัสที่เข้มงวดจึงปฏิเสธสตริงที่ไม่มีเครื่องหมายเหล่านี้ เปลี่ยนข้อผิดพลาดลึกลับให้เป็นเลขคณิตที่คาดเดาได้ ส่วน JWT อาจมีหนึ่ง = ไม่มี หรือสอง การตอบกลับ API อาจสิ้นสุดอย่างเรียบร้อยโดยไม่มีช่องว่างภายใน

สิ่งเหล่านี้แสดงถึงทางเลือกโดยเจตนา ไม่ใช่รูปแบบการใช้งาน กระบวนการถอดรหัสไม่จำเป็นต้องมีการเสริมกลไก มีช่องว่างภายในเพื่อทำให้เอาต์พุตไม่คลุมเครือ: เมื่อให้เฉพาะสตริง Base64 ที่ไม่มีข้อมูลเมตาเกี่ยวกับความยาว ตัวถอดรหัสจะอ่านช่องว่างภายในและรู้แน่ชัดว่าข้อมูลสิ้นสุดที่ใด Base64 เข้ารหัสกลุ่มสามไบต์เป็นอักขระสี่ตัว สามไบต์คือ 24 bits โดยจัดกลุ่มใหม่อย่างสมบูรณ์เป็นสี่ดัชนี 6 บิต แต่ละคนเลือกหนึ่งในสัญลักษณ์ 64 Base64 เมื่ออินพุตไม่เป็นทวีคูณของสาม ตัวเข้ารหัสจะเผชิญกับส่วนที่เหลือ: หนึ่งหรือสองไบต์ไม่สามารถหารด้วยสามเท่าๆ กัน

กลุ่มสามไบต์ บล็อกสี่อักขระ — เหตุใดความยาวอินพุตโมดูโล 3 จึงตัดสินใจว่าจะมีเครื่องหมาย = หนึ่งหรือสองปรากฏขึ้นหรือไม่

ตัวเข้ารหัสจะขยายกลุ่มเหล่านั้นโดยการเปลี่ยนบิตเป็นดัชนีแรก ปล่อยให้ค่าสุดท้ายเป็นศูนย์ เพื่อทำเครื่องหมายความตั้งใจนี้ มันจะต่อท้ายด้วยเครื่องหมาย =: ศูนย์สำหรับกลุ่มที่สมบูรณ์ หนึ่งรายการสำหรับรอบชิงชนะเลิศแบบสองไบต์ และสองรายการสำหรับรอบชิงชนะเลิศแบบหนึ่งไบต์ เลขคณิตถูกกำหนดไว้: การทราบความยาวอินพุตเป็นไบต์ทำให้คุณสามารถคำนวณการเติมได้ทันที หนึ่งไบต์จะสร้างอักขระ Base64 สองตัวบวกกับ = สองตัว สองไบต์สร้างอักขระสามตัวบวกหนึ่ง = สามไบต์สร้างสี่ไบต์โดยไม่มีช่องว่างภายใน

อินพุตใดๆ ที่ไม่ทวีคูณในสามไบต์จะมีช่องว่างภายใน สิ่งใดที่เป็นทวีคูณจะไม่เป็นเช่นนั้น นี่ไม่ใช่ทางเลือก แต่เป็นคณิตศาสตร์ สตริงที่ไม่มีช่องว่างภายในจะต้องแสดงถึงสามไบต์ สตริงที่มีหนึ่งเท่ากับจะต้องแทนสอง Padding เข้ารหัสความยาวอินพุตแบบโมดูโลสาม ตรวจสอบการเปลี่ยนแปลงของอินพุตทั้งสาม: single a, pair ab, triple abc ASCII a คือไบต์ 0x61; Base64 เข้ารหัสเป็น 0x61 00 00 โดยจัดกลุ่มใหม่เป็นกลุ่มหกบิต

บิตการเติมประกอบด้วยอะไรบ้างและเหตุใดตัวถอดรหัสที่เข้มงวดจึงตรวจสอบบิตเหล่านั้น - บิตที่ต้องเป็นศูนย์และการเข้ารหัสแบบบัญญัติหมายถึงอะไร

ดัชนี 24, 4, 0, 0 แมปกับ Y, E, A, A เนื่องจากกลุ่มสองกลุ่มอยู่ในระยะเติมเต็ม ตัวเข้ารหัสจึงต่อท้ายเครื่องหมาย = สองรายการ ทำให้เกิด YQ== สำหรับ ab ไบต์ 0x61 0x62 จะกลายเป็น 0x61 0x62 00. Bits จัดกลุ่มใหม่เป็นดัชนี 24, 22, 8, 0, เอาต์พุต YWI= สำหรับ abc ไบต์จะจัดกลุ่มใหม่เป็นดัชนี 24, 22, 9, 35 เอาต์พุต YWJj โดยไม่มีช่องว่างภายใน การแพดดิ้งไม่ได้เป็นไปตามอำเภอใจ: มันอยู่นอกเค้าโครงบิต เมื่อคุณถอดรหัสสตริง Base64 ตัวถอดรหัสจะอ่านอักขระแต่ละตัว ค้นหาดัชนีหกบิต และแพ็กบิตเป็นไบต์

สำหรับ YQ== อักขระ Y, E, A, A จะแยกออกเป็นบิต การจัดกลุ่มใหม่เป็นไบต์แปดบิตจะได้หนึ่งไบต์ 0x61 ตัวถอดรหัสละทิ้งการเติมบิต (ศูนย์ต่อท้าย) และรายงานหนึ่งไบต์ ตัวถอดรหัสที่เข้มงวดจะตรวจสอบว่าการเติมบิตเป็นศูนย์จริง ๆ หากไม่เป็นเช่นนั้น อินพุตจะไม่เป็นที่ยอมรับ หมายความว่าบุคคลที่เข้ารหัสโดยใช้เลย์เอาต์บิตที่แตกต่างกันและการถอดรหัสจะไม่ชัดเจน ระบบที่ละเว้นช่องว่างภายในทำให้เกิดการแลกเปลี่ยนโดยเจตนา เซ็กเมนต์ JWT ใช้ Base64url โดยไม่มีช่องว่างภายใน โดยอาศัยผู้บริโภคที่ทราบความยาวเอาต์พุตที่คาดหวังหรืออนุมาน

ตัวอย่างการทำงาน: การเข้ารหัส 'a', 'ab' และ 'abc' ด้วยมือ - สามอินพุต, ผลลัพธ์การเติมสามรายการ, แสดงทีละบิต

RFC 4648 อนุญาตให้ไม่มีช่องว่างภายใน แต่แนะนำให้ผู้ถอดรหัสยอมรับหากมี ไลบรารีโค้ดแตกต่างกัน: บางตัวจะคืนค่าช่องว่างภายในที่หายไปและดำเนินการต่อ คนอื่นจะล้มเหลว เมื่อคุณพบโทเค็นที่ไม่สามารถถอดรหัสได้ การต่อท้ายเครื่องหมาย = จำนวนที่ถูกต้องมักจะช่วยแก้ไขได้ จำเป็น = เครื่องหมายจะเป็นศูนย์เสมอ หนึ่งหรือสอง ขึ้นอยู่กับความยาวของสตริงโมดูโลสี่ หากความยาวสตริง Base64 ไม่ใช่ผลคูณของสี่ แสดงว่าช่องว่างภายในหายไปหรือเสียหายอย่างแน่นอน

ความยาวของ 5 ไม่สามารถเป็น Base64 ได้: อักขระที่สมบูรณ์แต่ละตัวเข้ารหัสหกบิต ดังนั้นอักขระสี่ตัวจึงเข้ารหัส 24 bits (สามไบต์) และห้าตัวเข้ารหัส 30 bits ซึ่งไม่ใช่ผลคูณของแปดและไม่สามารถกลายเป็นไบต์ได้ ตัวถอดรหัสจะต้องปฏิเสธสิ่งนี้หรือเพิ่มช่องว่างภายใน ถ้าความยาวเป็น 2 โมดูโล 4 ให้บวกสอง = ถ้า 3 โมดูโล 4 ให้เพิ่มหนึ่งรายการ = ถ้า 0 โมดูโล 4 ไม่ต้องเพิ่มเลย สตริงที่มีความยาว 3 ขาด = มันต้องการ; เพิ่มหนึ่งรายการและจะใช้งานได้ก่อนถอดรหัส

เหตุใดบางระบบจึงลดการเติมช่องว่างทั้งหมด — JWT เซ็กเมนต์และ URL-โทเค็นที่ปลอดภัยที่ละเว้น = และวิธีคืนค่าจากความยาว

การต่อสาย Base64 ที่บุนวมสองเส้นเข้าด้วยกัน หากเหลือช่องว่างภายในไว้ การเข้ารหัสที่แยกจากกันสองตัวที่รวมกันโดยตรงจะสร้างอักขระเสริมที่หลงทางซึ่งทำให้ตัวอักษรถอดรหัสแตก นี่คือเหตุผลว่าทำไมบางระบบจึงตัดช่องว่างภายในก่อนที่จะต่อกัน: โทเค็นที่ประกอบด้วยสามส่วน Base64url ที่ต่อกันด้วยจุดจะไม่มีช่องว่างภายในส่วน ทำให้การต่อข้อมูลตรงไปตรงมา หากสร้างค่า Base64 จากชิ้นส่วนต่างๆ ให้ตรวจสอบว่าแต่ละส่วนมีเบาะและแถบหรือเพิ่มช่องว่างภายในอย่างสม่ำเสมอก่อนดำเนินการใดๆ

ตัวเข้ารหัสและตัวถอดรหัส Base64 ใช้ RFC 4648 ซึ่งต้องมีการเติมตามค่าเริ่มต้น เมื่อคุณป้อนข้อความและขอเอาต์พุต base64 เครื่องมือจะสร้างผลลัพธ์แบบเสริม: รูปแบบมาตรฐาน หากคุณเห็น Base64 โดยไม่มีช่องว่างภายในและต้องการถอดรหัส ให้ตรวจสอบว่าตัวถอดรหัสของคุณยอมรับช่องว่างภายในที่ขาดหายไปหรือไม่ เครื่องมือยอมรับทั้งอินพุตแบบมีเบาะและแบบไม่มีเบาะและกู้คืนไบต์ต้นฉบับได้อย่างถูกต้อง สำหรับการดีบัก การนับความยาวแบบโมดูโล 4 จะบอกคุณว่ามีการถอดช่องว่างภายในออกหรือไม่ และสูตรจะบอกว่าควรมีช่องว่างภายในใดอยู่

ข้อผิดพลาดทั่วไป: การตัดแต่ง = ราวกับว่ามันเป็นช่องว่าง หรือการเชื่อมสายที่มีเบาะสองเส้นเข้าด้วยกัน — วิธีที่แต่ละสายทำให้การถอดรหัสเสียหาย

Base32 และ Base16 (เลขฐานสิบหก) มีกฎการเติมที่แตกต่างกันซึ่งกำหนดไว้ใน RFC 4648 ส่วน 6 และ 7 Base32 ใช้ = แต่กลุ่มสุดท้ายอาจเป็นอักขระ 2, 4, 5, 7 หรือ 8 อักขระ ขึ้นอยู่กับความยาวของอินพุตโมดูโลห้า เลขฐานสิบหกไม่จำเป็นต้องมีช่องว่างภายใน มันจะจับคู่หนึ่งไบต์กับอักขระสองตัวโดยไม่มีเศษเสมอ MIME การตัด Base64 สัมผัสกับช่องว่างภายใน: 76-สตริงที่ห่อคอลัมน์ยังคงมีช่องว่างภายในที่ส่วนท้ายสุด เพียงไม่กี่บรรทัดในภายหลัง

การทำความเข้าใจการเติมสำหรับ Base64 นั้นเกี่ยวกับการทำความเข้าใจเค้าโครงบิตและโมดูโลความยาวอินพุตสาม เมื่อคุณเห็นเลขคณิต การเติมจะกลายเป็นผลโดยตรง ไม่ใช่กฎเกณฑ์ที่ต้องจดจำ การแพ็ดดิ้งนั้นได้มาซึ่งไม่ได้มาจากเวทย์มนตร์

สิ่งนี้ไม่ครอบคลุมถึงกฎการขยายฐาน base32 และ base16 และแบบแผนความยาวบรรทัด MIME

ด้วยสตริง Base64 ที่มีความยาวเท่าใดก็ได้ คุณสามารถคืนค่ารูปแบบที่มีเบาะแบบ Canonical ได้โดยการแบ่งจำนวนอักขระด้วยสี่ นำเศษที่เหลือมาต่อท้ายด้วยจำนวนเครื่องหมาย = ที่สอดคล้องกัน นี่คือสาเหตุที่ Missing = สามารถแก้ไขได้ และเหตุใดตัวถอดรหัสที่เข้มงวดจึงสามารถให้อภัยได้: การเสริมจะมีข้อมูล (สาขาใดในสามกรณีที่คุณป้อนข้อมูลของคุณตกไป) แต่ข้อมูลนั้นสามารถคำนวณได้จากความยาวเพียงอย่างเดียว

ตัวเข้ารหัสและตัวถอดรหัส Base64 จะแสดงเอาต์พุตแบบบุนวมทันที เพื่อให้คุณสามารถเปรียบเทียบไบต์ที่ถอดรหัสกับข้อความต้นฉบับและตรวจสอบว่าการเดินทางไปกลับทำงานได้ Base64 และการเข้ารหัสที่เกี่ยวข้องขยายหลักการของการจัดกลุ่มบิตใหม่ให้มีความกว้างของอักขระที่แตกต่างกัน RFC 4648 ระบุทั้งสามอย่าง และการทำความเข้าใจสิ่งหนึ่งจะทำให้สิ่งอื่นเรียบง่ายตามแนวคิด ข้อมูลเชิงลึกที่สำคัญคือการเข้ารหัสนั้นเป็นการจัดการบิตล้วนๆ: เลือกขนาดตัวอักษร จัดกลุ่มบิตตามลำดับ ค้นหาแต่ละกลุ่มในตาราง

ประเด็นสำคัญ: การแพดดิ้งสามารถสืบทอดได้ ดังนั้น Missing = สามารถแก้ไขได้ — วิธีที่ตัวเข้ารหัสและตัวถอดรหัส Base64 แสดงให้คุณเห็นรูปแบบ Canonical ที่บุนวมของข้อความใด ๆ ที่คุณเข้ารหัส

การถอดรหัสแบบย้อนกลับ: ค้นหาอักขระแต่ละตัว แยกบิต จัดกลุ่มใหม่ เขียนไบต์ การทำแผนที่สองทางที่กำหนดขึ้นนี้เป็นเหตุผลว่าทำไม Base64 จึงทำงานได้อย่างน่าเชื่อถือในทุกแพลตฟอร์มและทุกภาษา ข้อผิดพลาดในการเข้ารหัสและถอดรหัสมักเกิดจากความเข้าใจผิดเกี่ยวกับช่องว่างภายในหรือความแตกต่างของตัวอักษร หากการถอดรหัสล้มเหลวโดยมีข้อผิดพลาดในการเติม ให้ตรวจสอบว่าตัวถอดรหัสต้องการ Canonical Base64 (เสริมอย่างเคร่งครัด) หรือยอมรับรูปแบบต่างๆ หากล้มเหลวโดยมีข้อผิดพลาดเกี่ยวกับอักขระ ให้ตรวจสอบว่าอินพุตเป็น base64url และตัวถอดรหัสต้องการ Base64 มาตรฐาน

ตัวเข้ารหัสและตัวถอดรหัส Base64 ยอมรับทั้งตัวอักษรและตรวจสอบความถูกต้องของช่องว่างภายในอย่างสม่ำเสมอ ดังนั้นตัวอย่างที่คำนวณด้วยมือจึงสามารถตรวจสอบได้ทันที การทดสอบการเข้ารหัสโดยการถอดรหัสกลับเป็นวิธีที่แน่นอนที่สุดในการตรวจจับข้อผิดพลาดก่อนที่จะทำให้เกิดปัญหาในการผลิต