Công cụ dành cho nhà phát triển · JSON trình định dạng và xác thực
Thứ tự khóa có quan trọng trong JSON không? Trật tự, bình đẳng và RFC 8785
· Lý lịch
json tiêu chuẩn xác nhận
Đặc tả JSON gọi các đối tượng không có thứ tự, nhưng các trình phân tích cú pháp và trình tuần tự thực sự thường giữ nguyên thứ tự và các sơ đồ ký phụ thuộc vào nó. Bài đăng này giải thích những gì thông số kỹ thuật nói, những gì việc triển khai thực hiện và cách chuẩn hóa giải quyết căng thẳng.
Dữ liệu giống nhau, byte khác nhau
`{"city":"Oslo","temp":4}` và `{"temp":4,"city":"Oslo"}` chứa hai tên và giá trị giống nhau nhưng byte nguồn của chúng khác nhau. Việc thụt lề có thể thêm nhiều khác biệt về văn bản mà không thay đổi giá trị được phân tích cú pháp. Đó là lý do tại sao “bằng JSON” cần có quy tắc so sánh: bạn đang so sánh văn bản, đối tượng được phân tích cú pháp hay biểu diễn chuẩn được xác định bởi giao thức khác?
ToolAcre có thể loại bỏ nhiễu khoảng trắng bằng cách định dạng cả hai tài liệu có cùng mức thụt lề. Nó cũng có thể sắp xếp đệ quy các khóa đối tượng khi tùy chọn đó được chọn. Việc sắp xếp thay đổi thứ tự thành viên một cách có chủ ý nhưng không bao giờ di chuyển các phần tử mảng, vì vị trí mảng biểu thị dữ liệu. Cả định dạng thông thường lẫn cách sắp xếp tùy chọn này đều không tạo ra RFC 8785 chính tắc JSON, do đó, đầu ra không được thay thế cho định dạng ký được chỉ định.
RFC 8259 nói gì — một đối tượng là một tập hợp không có thứ tự các cặp tên/value và việc triển khai có thể làm lộ thứ tự hoặc không
RFC 8259 mô tả một đối tượng là một tập hợp không có thứ tự các cặp tên/value. Do đó, phần mềm coi thứ tự thành viên là ý nghĩa của một đối tượng JSON thông thường sẽ dựa vào hành vi bên ngoài mô hình trừu tượng đó. Mảng được sắp xếp rõ ràng nên `["draft","final"]` không thể hoán đổi với `["final","draft"]`. Thứ tự đối tượng và thứ tự mảng không bao giờ được chuẩn hóa theo cùng một quy tắc.
RFC cũng lưu ý rằng các thư viện khác nhau ở chỗ chúng có hiển thị thứ tự thành viên cho người gọi hay không. Cảnh báo đó là đủ cho thiết kế di động: không mã hóa mức độ ưu tiên hoặc trình tự bằng cách đặt một thành viên đối tượng trước thành viên khác. Nếu trình tự quan trọng, hãy biểu diễn nó bằng một mảng hoặc một trường rõ ràng. Trình định dạng hiển thị thứ tự ổn định sẽ thuận tiện cho con người nhưng nó không biến vị trí thành thuộc tính cấp tiêu chuẩn của đối tượng.
Trình định dạng này thực sự làm gì
Khi tính năng sắp xếp bị vô hiệu hóa, ToolAcre sẽ phân tích cú pháp tài liệu và sắp xếp theo thứ tự giá trị JavaScript thu được. Đầu ra tuân theo hành vi liệt kê thuộc tính JavaScript thay vì bảo toàn byte luồng mã thông báo ban đầu cho byte. Hầu hết các khóa chuỗi thông thường xuất hiện theo thứ tự quen thuộc, trong khi các tên giống chỉ mục số nguyên có thể được đặt trước các tên khác. Các lựa chọn đánh vần và thoát số cũng có thể được chuẩn hóa trong quá trình sắp xếp lại.
Khi bật tính năng sắp xếp, trình định dạng sẽ xây dựng các đối tượng mới có khóa riêng được sắp xếp theo thứ tự bảng chữ cái ở mọi đối tượng lồng nhau. Đối với `{"z":{"b":1,"a":2},"items":[{"d":4,"c":3},"x"]}`, tên đối tượng trở thành `items`, `z`; tên đối tượng lồng nhau cũng được sắp xếp; và mảng vẫn chứa đối tượng của nó trước `"x"`. Sắp xếp các đối tượng bên trong một mảng không có nghĩa là sắp xếp chính mảng đó.
Khi thứ tự byte quan trọng
Trật tự văn bản quan trọng bất cứ khi nào một quá trình tiêu thụ byte chính xác thay vì giá trị trừu tượng. Hàm băm tệp, khóa bộ đệm, chữ ký số hoặc khác biệt dựa trên dòng thay đổi khi các thành viên di chuyển hoặc thay đổi khoảng trắng. Điều đó không mâu thuẫn với mô hình đối tượng không có thứ tự; điều đó có nghĩa là quá trình xung quanh đã chọn biểu diễn byte làm một phần đầu vào của nó. Các quy tắc đại diện sau đó phải rõ ràng và được chia sẻ.
Đối với các đánh giá định kỳ, việc thụt lề nhất quán và sắp xếp theo thứ tự bảng chữ cái tùy chọn có thể giúp dễ dàng xem các thay đổi hơn. Đối với công việc về mật mã hoặc giao thức, “có vẻ ổn định” không phải là một hợp đồng. Nhà sản xuất và người xác minh phải sử dụng thuật toán chuẩn hóa chính xác theo yêu cầu của giao thức của họ trước khi băm hoặc ký. Nếu không có thuật toán nào được đặt tên, đừng cho rằng đầu ra của ToolAcre sẽ khớp với một trình tuần tự hóa khác trên các phiên bản, thời gian chạy hoặc giá trị trường hợp cạnh.
Tại sao việc sắp xếp khóa không phải là RFC 8785
RFC 8785 xác định Lược đồ hợp chuẩn hóa JSON để tạo ra các byte có thể lặp lại từ dữ liệu tương thích. Công việc của nó rộng hơn việc đặt các phím theo thứ tự bảng chữ cái. Nó chỉ định việc sắp xếp thuộc tính xác định cùng với hành vi tuần tự hóa chính xác cho chuỗi và số, đồng thời áp đặt các ràng buộc đối với mô hình đầu vào. Việc thụt lề khá không phải là một phần của đầu ra chuẩn và việc sắp xếp nhận biết miền địa phương không phải là một phép tính gần đúng có thể chấp nhận được.
ToolAcre không đưa ra yêu cầu bồi thường RFC 8785. Tùy chọn sắp xếp của nó là tính năng dễ đọc được xếp lớp trên `JSON.parse` và `JSON.stringify`; nó không xác thực các điều kiện tiên quyết của I-JSON hoặc thay thế các quy tắc tuần tự hóa của RFC. Một giá trị như `1e-7`, khóa chứa các ký tự không phải ASCII hoặc một chuỗi thoát có thể tiết lộ sự khác biệt giữa trình định dạng được sắp xếp thông thường và trình chuẩn hóa tuân thủ. Sử dụng triển khai JCS đã được thử nghiệm khi cần có JCS.
Ví dụ hoạt động: so sánh hai tài liệu một cách công bằng
So sánh `{"meta":{"rev":2,"owner":"Mira"},"steps":["cut","pack"]}` với `{"steps":["cut","pack"],"meta":{"owner":"Mira","rev":2}}`. Định dạng cả hai có hai khoảng trắng và sắp xếp bị vô hiệu hóa: khoảng trắng trở nên nhất quán, nhưng thứ tự thành viên gốc và lồng nhau vẫn có thể khác nhau. Phân tích cú pháp cả hai và so sánh các trường dự định của chúng để thiết lập mức độ tương đương ở mức giá trị thay vì khai báo văn bản thô bằng nhau.
Bật tính năng sắp xếp khóa đệ quy và cả hai ví dụ đều hiển thị với cùng thứ tự đối tượng trong khi `steps` vẫn giữ nguyên `cut` rồi `pack`. Điều đó hữu ích đối với sự khác biệt về con người, nhưng nó vẫn là bằng chứng chuẩn hóa của ToolAcre chứ không phải RFC 8785 bằng chứng. Nếu mảng thứ hai là `["pack","cut"]`, các khóa sắp xếp sẽ hiển thị chính xác sự khác biệt đó vì việc thay đổi mảng sẽ thay đổi trình tự được biểu thị.
Điều này không bao gồm những gì
Việc sắp xếp khóa không xác định sự bình đẳng sâu sắc cho mọi ứng dụng. Tên trùng lặp được chấp nhận bởi `JSON.parse`, giữ giá trị cuối cùng, do đó việc định dạng có thể xóa bằng chứng cho thấy một nguồn chứa lặp lại. Số nguyên lớn có thể đã mất độ chính xác trong giá trị JavaScript. Một miền cũng có thể coi các mảng đã chọn là tập hợp, nhưng ToolAcre không thể suy ra quy tắc đó và do đó không bao giờ sắp xếp lại thứ tự các mảng.
Trình định dạng cũng không so sánh các lược đồ, áp dụng các giá trị mặc định, chuẩn hóa Unicode hoặc quyết định xem hai cách biểu diễn số có được chấp nhận đối với hệ thống hạ nguồn hay không. Đó là những hợp đồng riêng biệt. Sử dụng định dạng để giảm nhiễu khi trình bày, so sánh cấu trúc được xây dựng có mục đích để đảm bảo sự bằng nhau về giá trị và trình chuẩn hóa được chỉ định cho các byte chính xác. Việc trộn lẫn những công việc đó dưới từ “bình thường hóa” sẽ tạo ra niềm tin sai lầm về những gì thực sự được so sánh.
Rút ra: thứ tự không đáng kể đối với mô hình và có ý nghĩa đối với byte
Thứ tự thành viên đối tượng không có ý nghĩa trong mô hình dữ liệu RFC 8259, trong khi thứ tự mảng thì có. Các byte nguồn vẫn ghi lại cả thứ tự và khoảng trắng, do đó, các giá trị băm, chữ ký và khác biệt văn bản sẽ có những điểm khác biệt mà phép so sánh theo định hướng giá trị có thể bỏ qua. Nêu rõ lớp nào quan trọng trước khi chọn một công cụ: nhận dạng văn bản, giá trị tương đương được phân tích cú pháp và nhận dạng chuẩn do giao thức xác định là ba câu hỏi khác nhau.
ToolAcre chỉ hỗ trợ hai quy trình công việc đầu tiên một cách gián tiếp: định dạng nhất quán làm rõ sự khác biệt về văn bản và việc sắp xếp khóa đối tượng theo thứ tự bảng chữ cái đệ quy có thể làm cho việc so sánh của con người trở nên nhẹ nhàng hơn. Mảng không bao giờ được sắp xếp. Kết quả không phải là RFC 8785 hợp quy JSON và không được ký như thể nó là như vậy. Giữ nguyên đầu vào ban đầu khi bằng chứng từ vựng quan trọng, đặc biệt vì việc phân tích cú pháp các khóa trùng lặp chỉ giữ lại giá trị cuối cùng.