ไทย

เครื่องมือสำหรับนักพัฒนา · JSON ฟอร์แมตเตอร์ & เครื่องมือตรวจสอบความถูกต้อง

ลำดับคีย์มีความสำคัญใน JSON หรือไม่ การสั่งซื้อ ความเท่าเทียมกัน และ RFC 8785

· พื้นหลัง

json มาตรฐาน การตรวจสอบ

ลำดับคีย์มีความสำคัญใน JSON หรือไม่ การสั่งซื้อ ความเท่าเทียมกัน และ RFC 8785 แสดงด้วยโทเค็น JSON และขอบเขตการตรวจสอบที่แม่นยำ
ภาพประกอบเวกเตอร์ต้นฉบับ ToolAcre

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

ข้อมูลเดียวกัน ไบต์ต่างกัน

`{"city":"Oslo","temp":4}` และ `{"temp":4,"city":"Oslo"}` มีชื่อและค่าเหมือนกันสองชื่อ แต่ไบต์ของแหล่งที่มาต่างกัน การเยื้องสามารถเพิ่มความแตกต่างทางข้อความได้มากขึ้นโดยไม่ต้องเปลี่ยนค่าที่แยกวิเคราะห์ นั่นคือเหตุผลว่าทำไม “เท่ากับ JSON” จึงจำเป็นต้องมีกฎการเปรียบเทียบ: คุณกำลังเปรียบเทียบข้อความ วัตถุที่แยกวิเคราะห์ หรือการแสดงรูปแบบบัญญัติที่กำหนดโดยโปรโตคอลอื่นหรือไม่

ToolAcre สามารถลบสัญญาณรบกวนช่องว่างโดยการจัดรูปแบบเอกสารทั้งสองด้วยการเยื้องเดียวกัน นอกจากนี้ยังสามารถจัดเรียงคีย์ออบเจ็กต์แบบวนซ้ำได้เมื่อเลือกตัวเลือกนั้น การเรียงลำดับจะเปลี่ยนลำดับสมาชิกโดยเจตนาแต่ไม่เคยย้ายองค์ประกอบอาร์เรย์ เนื่องจากตำแหน่งของอาร์เรย์แสดงถึงข้อมูล ทั้งการจัดรูปแบบธรรมดาหรือการเรียงลำดับที่ไม่บังคับนี้จะสร้าง RFC 8785 ตามรูปแบบบัญญัติ JSON ดังนั้นเอาต์พุตจะต้องไม่แทนที่ด้วยรูปแบบการเซ็นชื่อที่ระบุ

สิ่งที่ RFC 8259 พูด — วัตถุคือคอลเลกชันที่ไม่เรียงลำดับของคู่ name/value และการนำไปใช้งานอาจเปิดเผยลำดับหรือไม่

RFC 8259 อธิบายออบเจ็กต์ว่าเป็นคอลเลกชั่นคู่ชื่อ/value ที่ไม่เรียงลำดับ ดังนั้นซอฟต์แวร์ที่ถือว่าลำดับของสมาชิกเป็นความหมายของอ็อบเจ็กต์ JSON ธรรมดานั้นจะขึ้นอยู่กับพฤติกรรมภายนอกโมเดลนามธรรมนั้น อาร์เรย์มีการเรียงลำดับอย่างชัดเจน ดังนั้น `["draft","final"]` จึงไม่สามารถใช้แทนกันกับ `["final","draft"]` ได้ ลำดับอ็อบเจ็กต์และลำดับอาร์เรย์จะต้องไม่ถูกทำให้เป็นมาตรฐานตามกฎเดียวกัน

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

สิ่งที่ฟอร์แมตเตอร์นี้ทำได้จริง

เมื่อปิดใช้งานการเรียงลำดับ ToolAcre จะแยกวิเคราะห์เอกสารและทำให้ค่า JavaScript ผลลัพธ์เป็นอนุกรม ผลลัพธ์เป็นไปตามพฤติกรรมการแจงนับคุณสมบัติ JavaScript แทนที่จะรักษาไบต์สตรีมโทเค็นดั้งเดิมไว้สำหรับไบต์ สตริงคีย์ธรรมดาส่วนใหญ่จะปรากฏในลำดับที่คุ้นเคย ในขณะที่ชื่อที่มีลักษณะคล้ายดัชนีจำนวนเต็มสามารถแสดงนำหน้าชื่ออื่นๆ ได้ ตัวเลือกการสะกดตัวเลขและ Escape สามารถทำให้เป็นมาตรฐานได้ในระหว่างการดำเนินการซ้ำ

เมื่อเปิดใช้งานการเรียงลำดับ ตัวจัดรูปแบบจะสร้างออบเจ็กต์ใหม่ซึ่งมีคีย์ของตัวเองเรียงตามตัวอักษรในทุกออบเจ็กต์ที่ซ้อนกัน สำหรับ `{"z":{"b":1,"a":2},"items":[{"d":4,"c":3},"x"]}` ชื่ออ็อบเจ็กต์จะกลายเป็น `items`, `z`; ชื่อวัตถุที่ซ้อนกันจะถูกจัดเรียงด้วย และอาร์เรย์ยังคงมีวัตถุอยู่ก่อน `"x"` การเรียงลำดับวัตถุภายในอาร์เรย์ไม่ได้หมายถึงการเรียงลำดับอาร์เรย์นั้นเอง

เมื่อลำดับไบต์มีความสำคัญ

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

สำหรับการตรวจสอบเป็นประจำ การเยื้องที่สอดคล้องกันและการเรียงลำดับตัวอักษรที่เป็นตัวเลือกจะช่วยให้มองเห็นการเปลี่ยนแปลงได้ง่ายขึ้น สำหรับงานด้านการเข้ารหัสหรือโปรโตคอล “ดูมีเสถียรภาพ” ไม่ใช่สัญญา ผู้ผลิตและผู้ตรวจสอบต้องใช้อัลกอริธึมการกำหนดรูปแบบมาตรฐานตามที่โปรโตคอลกำหนดก่อนที่จะแฮชหรือลงนาม หากไม่มีชื่ออัลกอริทึม อย่าถือว่าเอาต์พุตของ ToolAcre จะจับคู่ซีเรียลไลเซอร์อื่นในเวอร์ชัน รันไทม์ หรือค่า Edge-case

เหตุใดการเรียงลำดับคีย์จึงไม่ RFC 8785

RFC 8785 กำหนด JSON Canonicalization Scheme สำหรับการสร้างไบต์ที่ทำซ้ำได้จากข้อมูลที่เข้ากันได้ งานของมันกว้างกว่าการวางคีย์ตามลำดับตัวอักษร โดยจะระบุการเรียงลำดับคุณสมบัติตามที่กำหนดพร้อมกับพฤติกรรมการทำให้เป็นอนุกรมที่แน่นอนสำหรับสตริงและตัวเลข และกำหนดข้อจำกัดในโมเดลอินพุต การเยื้องแบบสวยไม่ได้เป็นส่วนหนึ่งของเอาต์พุตตามรูปแบบบัญญัติ และการเรียงลำดับตามสถานที่นั้นก็ไม่ใช่การประมาณที่ยอมรับได้

ToolAcre ไม่มีการอ้างสิทธิ์ RFC 8785 ตัวเลือกการจัดเรียงของมันคือคุณลักษณะที่สามารถอ่านได้ซึ่งมีเลเยอร์อยู่เหนือ `JSON.parse` และ `JSON.stringify`; มันไม่ได้ตรวจสอบเงื่อนไขเบื้องต้นของ I-JSON หรือแทนที่กฎการทำให้เป็นอนุกรมของ RFC ค่า เช่น `1e-7` คีย์ที่มีอักขระที่ไม่ใช่ ASCII หรือสตริงที่ใช้ Escape สามารถเปิดเผยความแตกต่างระหว่างฟอร์แมตเตอร์ที่เรียงลำดับทั่วไปและ Canonicalizer ที่สอดคล้องกัน ใช้การใช้งาน JCS ที่ผ่านการทดสอบแล้ว เมื่อจำเป็นต้องใช้ JCS

ตัวอย่างการทำงาน: เปรียบเทียบเอกสารสองฉบับอย่างยุติธรรม

เปรียบเทียบ `{"meta":{"rev":2,"owner":"Mira"},"steps":["cut","pack"]}` กับ `{"steps":["cut","pack"],"meta":{"owner":"Mira","rev":2}}` จัดรูปแบบทั้งที่มีช่องว่างสองช่องและปิดใช้งานการเรียงลำดับ: ช่องว่างจะสอดคล้องกัน แต่ลำดับรากและลำดับสมาชิกที่ซ้อนกันอาจแตกต่างกัน แยกวิเคราะห์ทั้งสองช่องและเปรียบเทียบช่องที่ต้องการเพื่อสร้างความเท่าเทียมกันระดับค่า แทนที่จะประกาศข้อความดิบว่าเท่ากัน

เปิดการเรียงลำดับคีย์แบบเรียกซ้ำ และทั้งสองตัวอย่างจะแสดงผลด้วยลำดับออบเจ็กต์เดียวกัน ขณะที่ `steps` ยังคงอยู่ `cut` จากนั้น `pack` นั่นมีประโยชน์สำหรับความแตกต่างของมนุษย์ แต่ยังคงเป็น ToolAcre ที่ทำให้เป็นมาตรฐาน ไม่ใช่ RFC 8785 พิสูจน์ หากอาร์เรย์ที่สองคือ `["pack","cut"]` คีย์การเรียงลำดับจะทำให้มองเห็นความแตกต่างได้อย่างถูกต้อง เนื่องจากการเปลี่ยนอาร์เรย์จะเปลี่ยนลำดับที่แสดง

สิ่งนี้ไม่ครอบคลุมถึง

การเรียงลำดับคีย์ไม่ได้กำหนดความเท่าเทียมกันเชิงลึกสำหรับทุกแอปพลิเคชัน ชื่อที่ซ้ำกันได้รับการยอมรับโดย `JSON.parse` ซึ่งจะเก็บค่าสุดท้ายไว้ ดังนั้นการจัดรูปแบบจึงสามารถลบหลักฐานที่แสดงว่าแหล่งข้อมูลหนึ่งมีการซ้ำกัน จำนวนเต็มขนาดใหญ่อาจสูญเสียความแม่นยำในค่า JavaScript แล้ว โดเมนอาจถือว่าอาร์เรย์ที่เลือกเป็นชุด แต่ ToolAcre ไม่สามารถอนุมานกฎนั้นได้ ดังนั้นจึงไม่ต้องเรียงลำดับอาร์เรย์ใหม่

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

Takeaway: ลำดับไม่มีนัยสำคัญต่อโมเดลและมีนัยสำคัญต่อไบต์

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

ToolAcre รองรับสองเวิร์กโฟลว์แรกทางอ้อมเท่านั้น: การจัดรูปแบบที่สอดคล้องกันทำให้ความแตกต่างทางข้อความชัดเจนขึ้น และการเรียงลำดับคีย์วัตถุที่เรียงตามตัวอักษรแบบเรียกซ้ำสามารถทำให้การเปรียบเทียบของมนุษย์เงียบลง อาร์เรย์จะไม่เรียงลำดับ ผลลัพธ์ไม่ใช่ RFC 8785 ตามรูปแบบบัญญัติ JSON และไม่ควรลงนามเหมือนเช่นเดิม รักษาอินพุตดั้งเดิมไว้เมื่อหลักฐานทางคำศัพท์มีความสำคัญ โดยเฉพาะอย่างยิ่งเนื่องจากการแยกวิเคราะห์คีย์ที่ซ้ำกันจะคงไว้เฉพาะค่าสุดท้ายเท่านั้น