Alat pembangun · JSON pemformat & pengesah
Adakah pesanan kunci penting dalam JSON? Susunan, kesaksamaan dan RFC 8785
· Latar belakang
json piawaian pengesahan
Spesifikasi JSON memanggil objek tidak tertib, tetapi penghurai dan penyeri bersiri sebenar biasanya mengekalkan susunan, dan skim menandatangani bergantung padanya. Siaran ini menguraikan perkara yang dinyatakan oleh spesifikasi, pelaksanaan yang dilakukan dan cara kanonik menyelesaikan ketegangan.
Data yang sama, bait yang berbeza
`{"city":"Oslo","temp":4}` dan `{"temp":4,"city":"Oslo"}` mengandungi dua nama dan nilai yang sama, namun bait sumbernya berbeza. Lekukan boleh menambah lebih banyak perbezaan teks tanpa mengubah nilai yang dihuraikan. Itulah sebabnya "setara JSON" memerlukan peraturan perbandingan: adakah anda membandingkan teks, objek yang dihuraikan atau perwakilan kanonik yang ditakrifkan oleh protokol lain?
ToolAcre boleh mengalih keluar hingar ruang kosong dengan memformatkan kedua-dua dokumen dengan lekukan yang sama. Ia juga boleh mengisih kekunci objek secara rekursif apabila pilihan itu dipilih. Isih menukar susunan ahli dengan sengaja tetapi tidak sekali-kali memindahkan elemen tatasusunan, kerana kedudukan tatasusunan mewakili data. Pemformatan biasa mahupun jenis pilihan ini tidak menghasilkan RFC 8785 berkanun JSON, jadi output tidak boleh digantikan dengan format tandatangan yang ditentukan.
Apa yang RFC 8259 katakan — objek ialah koleksi pasangan nama/value yang tidak tertib dan pelaksanaan mungkin mendedahkan tertib atau tidak
RFC 8259 menerangkan objek sebagai koleksi pasangan nama/value yang tidak tertib. Oleh itu, perisian yang menganggap pesanan ahli sebagai maksud objek JSON biasa bergantung pada tingkah laku di luar model abstrak itu. Tatasusunan disusun secara eksplisit, jadi `["draft","final"]` tidak boleh ditukar ganti dengan `["final","draft"]`. Tertib objek dan susunan tatasusunan tidak boleh dinormalkan oleh peraturan yang sama.
RFC juga menyatakan bahawa perpustakaan berbeza sama ada mereka mendedahkan pesanan ahli kepada pemanggil. Amaran itu sudah cukup untuk reka bentuk mudah alih: jangan kodkan keutamaan atau urutan dengan meletakkan satu ahli objek sebelum yang lain. Jika jujukan penting, nyatakan dengan tatasusunan atau medan eksplisit. Pemformat yang menunjukkan susunan yang stabil adalah mudah untuk manusia, tetapi ia tidak mengubah kedudukan menjadi sifat peringkat standard objek.
Apa sebenarnya yang dilakukan oleh pemformat ini
Dengan pengisihan dilumpuhkan, ToolAcre menghuraikan dokumen dan menyerikan nilai JavaScript yang terhasil. Output mengikuti JavaScript gelagat penghitungan harta daripada mengekalkan bait aliran token asal untuk bait. Kebanyakan kunci rentetan biasa muncul dalam susunan biasa, manakala nama seperti indeks integer boleh dipancarkan mendahului nama lain. Ejaan nombor dan pilihan pelepasan aksara juga boleh dinormalisasi semasa pensirialisasian semula.
Dengan pengisihan didayakan, pemformat membina objek baharu yang kuncinya sendiri disusun mengikut abjad pada setiap objek bersarang. Untuk `{"z":{"b":1,"a":2},"items":[{"d":4,"c":3},"x"]}`, nama objek menjadi `items`, `z`; nama objek bersarang juga diisih; dan tatasusunan masih mengandungi objeknya sebelum `"x"`. Mengisih objek di dalam tatasusunan tidak bermakna mengisih tatasusunan itu sendiri.
Apabila pesanan bait penting
Tertib teks penting apabila proses menggunakan bait tepat dan bukannya nilai abstrak. Cincang fail, kunci cache, tandatangan digital atau perbezaan berasaskan baris berubah apabila ahli berpindah atau ruang kosong berubah. Itu tidak bercanggah dengan model objek tidak tertib; ia bermakna proses sekeliling telah memilih perwakilan bait sebagai sebahagian daripada inputnya. Peraturan perwakilan kemudiannya mestilah eksplisit dan dikongsi.
Untuk semakan rutin, lekukan yang konsisten dan pengisihan abjad pilihan boleh membuat perubahan lebih mudah dilihat. Untuk kerja kriptografi atau protokol, "kelihatan stabil" bukanlah kontrak. Pengeluar dan pengesah mesti menggunakan algoritma kanonikisasi yang tepat yang diperlukan oleh protokol mereka sebelum pencincangan atau menandatangani. Jika tiada algoritma dinamakan, jangan anggap output ToolAcre akan sepadan dengan penyeri bersiri lain merentas versi, masa jalan atau nilai huruf tepi.
Mengapa pengisihan kunci tidak RFC 8785
RFC 8785 mentakrifkan JSON Skim Kanonialisasi untuk menghasilkan bait berulang daripada data yang serasi. Kerjanya lebih luas daripada meletakkan kunci dalam susunan abjad. Ia menentukan pengisihan sifat deterministik bersama-sama dengan tingkah laku bersiri yang tepat untuk rentetan dan nombor dan mengenakan kekangan pada model input. Lekukan cantik bukan sebahagian daripada keluaran kanonik dan pengisihan sedar setempat bukanlah anggaran yang boleh diterima.
ToolAcre tidak membuat tuntutan RFC 8785. Pilihan isihannya ialah ciri kebolehbacaan berlapis di atas `JSON.parse` dan `JSON.stringify`; ia tidak mengesahkan prasyarat I-JSON atau menggantikan peraturan siri RFC. Nilai seperti `1e-7`, kunci yang mengandungi aksara bukan ASCII atau rentetan yang dilepaskan boleh mendedahkan perbezaan antara pemformat diisih kasual dan kanonik yang mematuhi. Gunakan pelaksanaan JCS yang diuji apabila JCS diperlukan.
Contoh kerja: membandingkan dua dokumen secara adil
Bandingkan `{"meta":{"rev":2,"owner":"Mira"},"steps":["cut","pack"]}` dengan `{"steps":["cut","pack"],"meta":{"owner":"Mira","rev":2}}`. Formatkan kedua-duanya dengan dua ruang dan pengisihan dilumpuhkan: ruang kosong menjadi konsisten, tetapi pesanan akar dan ahli bersarang masih boleh berbeza. Parsing kedua-duanya dan bandingkan medan yang dimaksudkan untuk mewujudkan kesetaraan tahap nilai dan bukannya mengisytiharkan teks mentah sama.
Hidupkan pengisihan kunci rekursif dan kedua-dua contoh dipaparkan dengan susunan objek yang sama manakala `steps` kekal `cut` kemudian `pack`. Itu berguna untuk perbezaan manusia, tetapi ia masih ToolAcre's normalisasi, bukan RFC 8785 bukti. Jika tatasusunan kedua ialah `["pack","cut"]`, kekunci pengisihan dengan betul akan membiarkan perbezaan itu kelihatan kerana menukar tatasusunan akan mengubah jujukan yang diwakili.
Perkara ini tidak meliputi
Pengisihan kunci tidak menentukan kesaksamaan yang mendalam untuk setiap aplikasi. Nama pendua diterima oleh `JSON.parse`, yang mengekalkan nilai terakhir, jadi pemformatan boleh memadamkan bukti bahawa satu sumber mengandungi berulang. Integer yang besar mungkin telah kehilangan ketepatan dalam nilai JavaScript. Domain juga boleh menggunakan tatasusunan yang dipilih sebagai set, tetapi ToolAcre tidak boleh membuat kesimpulan peraturan itu dan oleh itu tidak sekali-kali menyusun semula tatasusunan.
Pemformat juga tidak membandingkan skema, menggunakan lalai, menormalkan Unikod atau memutuskan sama ada dua perwakilan nombor boleh diterima oleh sistem hiliran. Itu adalah kontrak berasingan. Gunakan pemformatan untuk mengurangkan hingar pembentangan, perbandingan struktur yang dibina khas untuk kesaksamaan nilai, dan kanonik yang ditentukan untuk bait yang tepat. Mencampurkan pekerjaan tersebut di bawah perkataan "normalize" mewujudkan keyakinan palsu tentang perkara yang sebenarnya dibandingkan.
Bawa pulang: pesanan tidak penting kepada model dan penting kepada bait
Pesanan ahli objek tidak membawa maksud dalam model data RFC 8259, manakala susunan tatasusunan bermakna. Bait sumber masih merekodkan kedua-dua susunan dan ruang kosong, jadi cincang, tandatangan dan perbezaan teks memerhatikan perbezaan yang perbandingan berorientasikan nilai mungkin diabaikan. Nyatakan lapisan mana yang penting sebelum memilih alat: identiti tekstual, kesetaraan nilai dihuraikan dan identiti kanonik yang ditakrifkan protokol ialah tiga soalan berbeza.
ToolAcre menyokong dua aliran kerja pertama secara tidak langsung sahaja: pemformatan yang konsisten menjelaskan perbezaan teks dan pengisihan kekunci objek abjad rekursif boleh menjadikan perbandingan manusia lebih senyap. Tatasusunan tidak pernah diisih. Hasilnya bukan RFC 8785 berkanun JSON dan tidak sepatutnya ditandatangani seolah-olah ianya. Kekalkan input asal apabila bukti leksikal penting, terutamanya kerana menghuraikan kunci pendua sahaja mengekalkan nilai terakhir.