Alat pengembang · JSON pemformat & validator
Apakah urutan kunci penting di JSON? Keteraturan, kesetaraan dan RFC 8785
· Latar belakang
json standar validasi
Spesifikasi JSON memanggil objek tidak berurutan, tetapi parser dan serialiser sebenarnya biasanya menjaga keteraturan, dan skema penandatanganan bergantung padanya. Postingan ini menguraikan apa yang disebutkan dalam spesifikasi, apa yang dilakukan implementasinya, dan bagaimana kanonikalisasi menyelesaikan ketegangan tersebut.
Data yang sama, byte berbeda
`{"city":"Oslo","temp":4}` dan `{"temp":4,"city":"Oslo"}` berisi dua nama dan nilai yang sama, namun byte sumbernya berbeda. Indentasi dapat menambahkan lebih banyak perbedaan tekstual tanpa mengubah nilai yang diurai. Itulah sebabnya “JSON” yang sama memerlukan aturan perbandingan: apakah Anda membandingkan teks, objek yang diurai, atau representasi kanonik yang ditentukan oleh protokol lain?
ToolAcre dapat menghilangkan derau spasi dengan memformat kedua dokumen dengan lekukan yang sama. Itu juga dapat mengurutkan kunci objek secara rekursif ketika opsi itu dipilih. Pengurutan mengubah urutan anggota dengan sengaja tetapi tidak pernah memindahkan elemen array, karena posisi array mewakili data. Baik pemformatan biasa maupun pengurutan opsional ini tidak menghasilkan RFC 8785 kanonik JSON, sehingga keluarannya tidak boleh diganti dengan format penandatanganan yang ditentukan.
Apa yang RFC 8259 katakan - sebuah objek adalah kumpulan pasangan nama/value yang tidak berurutan, dan implementasinya dapat memperlihatkan keteraturan atau tidak
RFC 8259 mendeskripsikan objek sebagai kumpulan pasangan nama/value yang tidak berurutan. Oleh karena itu, perangkat lunak yang memperlakukan urutan anggota sebagai makna objek JSON biasa bergantung pada perilaku di luar model abstrak tersebut. Array diurutkan secara eksplisit, jadi `["draft","final"]` tidak dapat dipertukarkan dengan `["final","draft"]`. Urutan objek dan urutan array tidak boleh dinormalisasi dengan aturan yang sama.
RFC juga mencatat bahwa perpustakaan berbeda dalam hal mereka mengekspos pemesanan anggota kepada penelepon. Peringatan itu cukup untuk desain portabel: jangan mengkodekan prioritas atau urutan dengan menempatkan satu anggota objek sebelum yang lain. Jika urutan penting, nyatakan dengan array atau bidang eksplisit. Pemformat yang menunjukkan tatanan stabil nyaman bagi manusia, namun tidak mengubah posisi menjadi properti tingkat standar objek.
Apa yang sebenarnya dilakukan oleh pemformat ini
Dengan pengurutan dinonaktifkan, ToolAcre mem-parsing dokumen dan membuat serial nilai JavaScript yang dihasilkan. Outputnya mengikuti perilaku enumerasi properti JavaScript daripada mempertahankan byte aliran token asli demi byte. Sebagian besar kunci string biasa muncul dalam urutan yang lazim, sementara nama seperti indeks bilangan bulat dapat dikeluarkan sebelum nama lainnya. Pilihan ejaan angka dan escape juga dapat dinormalisasi selama serialisasi ulang.
Dengan pengurutan diaktifkan, pemformat membuat objek baru yang kuncinya disusun menurut abjad di setiap objek yang disarangkan. Untuk `{"z":{"b":1,"a":2},"items":[{"d":4,"c":3},"x"]}`, nama objeknya menjadi `items`, `z`; nama objek bersarang juga diurutkan; dan array masih berisi objeknya sebelum `"x"`. Mengurutkan objek di dalam array tidak berarti mengurutkan array itu sendiri.
Ketika urutan byte penting
Urutan tekstual penting setiap kali suatu proses menggunakan byte yang tepat, bukan nilai abstrak. Hash file, kunci cache, tanda tangan digital, atau perbedaan berbasis baris berubah ketika anggota berpindah atau perubahan spasi. Hal ini tidak bertentangan dengan model objek tidak berurutan; itu berarti proses di sekitarnya telah memilih representasi byte sebagai bagian dari masukannya. Aturan representasi kemudian harus eksplisit dan dibagikan.
Untuk tinjauan rutin, indentasi yang konsisten dan pengurutan berdasarkan abjad opsional dapat membuat perubahan lebih mudah dilihat. Untuk pekerjaan kriptografi atau protokol, “tampak stabil” bukanlah sebuah kontrak. Produser dan verifikator harus menggunakan algoritme kanonikalisasi yang tepat yang disyaratkan oleh protokol mereka sebelum melakukan hashing atau penandatanganan. Jika tidak ada algoritme yang disebutkan, jangan berasumsi keluaran ToolAcre akan cocok dengan serializer lain di seluruh versi, waktu proses, atau nilai kasus tepi.
Mengapa penyortiran kunci tidak RFC 8785
RFC 8785 mendefinisikan Skema Kanonikalisasi JSON untuk menghasilkan byte berulang dari data yang kompatibel. Tugasnya lebih luas dibandingkan penempatan kunci sesuai urutan abjad. Ini menentukan pengurutan properti deterministik bersama dengan perilaku serialisasi yang tepat untuk string dan angka dan menerapkan batasan pada model input. Indentasi yang cantik bukan bagian dari keluaran kanonik, dan pengurutan berdasarkan lokasi bukanlah perkiraan yang dapat diterima.
ToolAcre tidak mengajukan klaim RFC 8785. Opsi pengurutannya adalah fitur keterbacaan yang berlapis pada `JSON.parse` dan `JSON.stringify`; itu tidak memvalidasi prasyarat I-JSON atau menggantikan aturan serialisasi RFC. Nilai seperti `1e-7`, kunci yang berisi karakter non-ASCII, atau string yang lolos dapat mengungkapkan perbedaan antara pemformat yang diurutkan biasa dan kanonikalisasi yang sesuai. Gunakan implementasi JCS yang teruji ketika JCS diperlukan.
Contoh praktis: membandingkan dua dokumen secara adil
Bandingkan `{"meta":{"rev":2,"owner":"Mira"},"steps":["cut","pack"]}` dengan `{"steps":["cut","pack"],"meta":{"owner":"Mira","rev":2}}`. Format keduanya dengan dua spasi dan pengurutan dinonaktifkan: spasi menjadi konsisten, namun urutan anggota akar dan yang disarangkan masih dapat berbeda. Parsing keduanya dan bandingkan bidang yang dimaksudkan untuk menetapkan kesetaraan tingkat nilai daripada menyatakan teks mentah sama.
Aktifkan pengurutan kunci rekursif dan kedua contoh dirender dengan urutan objek yang sama sementara `steps` tetap `cut` lalu `pack`. Hal ini berguna untuk perbedaan manusia, namun ini masih merupakan normalisasi ToolAcre, bukan bukti RFC 8785. Jika larik kedua adalah `["pack","cut"]`, kunci pengurutan akan membuat perbedaan tersebut terlihat dengan benar karena mengubah larik akan mengubah urutan yang diwakili.
Hal ini tidak tercakup dalam hal ini
Penyortiran kunci tidak mendefinisikan kesetaraan mendalam untuk setiap aplikasi. Nama duplikat diterima oleh `JSON.parse`, yang mempertahankan nilai terakhir, sehingga pemformatan dapat menghapus bukti bahwa satu sumber berisi pengulangan. Bilangan bulat besar mungkin sudah kehilangan presisi pada nilai JavaScript. Sebuah domain juga dapat memperlakukan array yang dipilih sebagai kumpulan, namun ToolAcre tidak dapat menyimpulkan aturan tersebut dan oleh karena itu tidak pernah menyusun ulang array.
Pemformat juga tidak membandingkan skema, menerapkan default, menormalkan Unicode, atau memutuskan apakah representasi dua angka dapat diterima oleh sistem hilir. Itu adalah kontrak terpisah. Gunakan pemformatan untuk mengurangi gangguan presentasi, perbandingan struktural yang dibuat khusus untuk kesetaraan nilai, dan kanonikalisasi yang ditentukan untuk byte yang tepat. Menggabungkan pekerjaan-pekerjaan tersebut dengan kata “normalisasi” menciptakan keyakinan palsu tentang apa yang sebenarnya dibandingkan.
Kesimpulan: urutan tidak signifikan bagi model dan signifikan bagi byte
Urutan anggota objek tidak memiliki arti dalam model data RFC 8259, sedangkan urutan array memiliki arti. Byte sumber masih mencatat urutan dan spasi, jadi hash, tanda tangan, dan perbedaan teks mengamati perbedaan yang mungkin diabaikan oleh perbandingan berorientasi nilai. Nyatakan lapisan mana yang penting sebelum memilih alat: identitas tekstual, kesetaraan nilai yang diurai, dan identitas kanonik yang ditentukan protokol adalah tiga pertanyaan berbeda.
ToolAcre mendukung dua alur kerja pertama hanya secara tidak langsung: pemformatan yang konsisten memperjelas perbedaan tekstual, dan pengurutan kunci objek berdasarkan abjad secara rekursif dapat membuat perbandingan manusia menjadi lebih tenang. Array tidak pernah diurutkan. Hasilnya bukan RFC 8785 kanonik JSON dan tidak boleh ditandatangani seolah-olah memang demikian. Pertahankan masukan asli ketika bukti leksikal penting, terutama karena penguraian kunci duplikat hanya mempertahankan nilai terakhir.