Herramientas de desarrollo · JSON formateador y validador
¿Importa el orden de las claves en JSON? Ordenamiento, igualdad y RFC 8785
· Antecedentes
json estándares validación
La especificación JSON llama a objetos desordenados, pero los analizadores y serializadores reales generalmente conservan el orden y los esquemas de firma dependen de ello. Esta publicación desenreda lo que dice la especificación, qué hacen las implementaciones y cómo la canonicalización resuelve la tensión.
Mismos datos, diferentes bytes
`{"city":"Oslo","temp":4}` y `{"temp":4,"city":"Oslo"}` contienen los mismos dos nombres y valores, pero sus bytes de origen difieren. La sangría puede agregar muchas más diferencias textuales sin cambiar ninguno de los valores analizados. Es por eso que “igual JSON” necesita una regla de comparación: ¿está comparando texto, objetos analizados o una representación canónica definida por otro protocolo?
ToolAcre puede eliminar el ruido de los espacios en blanco formateando ambos documentos con la misma sangría. También puede ordenar recursivamente claves de objetos cuando se selecciona esa opción. La clasificación cambia deliberadamente el orden de los miembros, pero nunca mueve los elementos de la matriz, porque la posición de la matriz representa datos. Ni el formato ordinario ni esta clasificación opcional producen RFC 8785 canónico JSON, por lo que la salida no debe sustituirse por un formato de firma específico.
Lo que dice RFC 8259: un objeto es una colección desordenada de pares de nombres /value y las implementaciones pueden exponer el orden o no
RFC 8259 describe un objeto como una colección desordenada de pares de nombre /value. Por lo tanto, el software que trata el orden de los miembros como el significado de un objeto JSON ordinario se basa en un comportamiento fuera de ese modelo abstracto. Las matrices están ordenadas explícitamente, por lo que `["draft","final"]` no es intercambiable con `["final","draft"]`. El orden de los objetos y el orden de las matrices nunca deben normalizarse mediante la misma regla.
El RFC también señala que las bibliotecas difieren en si exponen los pedidos de los miembros a las personas que llaman. Esa advertencia es suficiente para el diseño portátil: no codifique prioridad o secuencia colocando un miembro de objeto antes que otro. Si la secuencia importa, represéntela con una matriz o un campo explícito. Un formateador que muestre un orden estable es conveniente para los humanos, pero no convierte la posición en una propiedad del objeto a nivel de estándares.
Qué hace realmente este formateador
Con la clasificación deshabilitada, ToolAcre analiza el documento y serializa el valor de JavaScript resultante. La salida sigue el comportamiento de enumeración de propiedades de JavaScript en lugar de preservar el flujo de token original byte por byte. La mayoría de las claves de cadena ordinarias aparecen en un orden familiar, mientras que los nombres similares a índices enteros se pueden emitir antes que otros nombres. La ortografía de números y las opciones de escape también se pueden normalizar durante la reserialización.
Con la clasificación habilitada, el formateador crea nuevos objetos cuyas propias claves están ordenadas alfabéticamente en cada objeto anidado. Para `{"z":{"b":1,"a":2},"items":[{"d":4,"c":3},"x"]}`, los nombres de los objetos se convierten en `items`, `z`; los nombres de los objetos anidados también están ordenados; y la matriz todavía contiene su objeto antes de `"x"`. Ordenar objetos dentro de una matriz no significa ordenar la matriz en sí.
Cuando el orden de los bytes importa
El orden del texto es importante siempre que un proceso consume bytes exactos en lugar del valor abstracto. Un hash de archivo, una clave de caché, una firma digital o una diferencia basada en líneas cambian cuando los miembros se mueven o cambian los espacios en blanco. Eso no contradice el modelo de objetos desordenados; significa que el proceso circundante ha elegido una representación de bytes como parte de su entrada. Las reglas de representación deben entonces ser explícitas y compartidas.
Para revisiones de rutina, la sangría consistente y la clasificación alfabética opcional pueden hacer que los cambios sean más fáciles de ver. Para trabajos criptográficos o de protocolo, "parece estable" no es un contrato. El productor y el verificador deben utilizar el algoritmo de canonicalización exacto requerido por su protocolo antes del hash o la firma. Si no se nombra ningún algoritmo, no asuma que la salida de ToolAcre coincidirá con otro serializador en todas las versiones, tiempos de ejecución o valores de casos extremos.
Por qué la clasificación de claves no es RFC 8785
RFC 8785 define el esquema de canonicalización JSON para producir bytes repetibles a partir de datos compatibles. Su trabajo es más amplio que colocar claves en orden alfabético. Especifica una clasificación de propiedades determinista junto con un comportamiento de serialización exacto para cadenas y números e impone restricciones al modelo de entrada. La sangría bonita no forma parte de la salida canónica y la clasificación según la configuración regional no es una aproximación aceptable.
ToolAcre no realiza ningún reclamo RFC 8785. Su opción de clasificación es una característica de legibilidad superpuesta a `JSON.parse` y `JSON.stringify`; no valida las condiciones previas I-JSON ni reemplaza las reglas de serialización del RFC. Un valor como `1e-7`, una clave que contiene caracteres no ASCII o una cadena con escape puede revelar diferencias entre un formateador ordenado informal y un canonicalizador conforme. Utilice una implementación JCS probada cuando se requiera JCS.
Ejemplo resuelto: comparar dos documentos de manera justa
Compare `{"meta":{"rev":2,"owner":"Mira"},"steps":["cut","pack"]}` con `{"steps":["cut","pack"],"meta":{"owner":"Mira","rev":2}}`. Formatee ambos con dos espacios y clasificación deshabilitada: los espacios en blanco se vuelven consistentes, pero el orden de los miembros raíz y anidados aún puede diferir. Analice ambos y compare sus campos previstos para establecer una equivalencia de nivel de valor en lugar de declarar igual el texto sin formato.
Active la clasificación por clave recursiva y ambos ejemplos se renderizarán con el mismo orden de objetos mientras `steps` permanece `cut` y luego `pack`. Esto es útil para una diferenciación humana, pero sigue siendo una normalización de ToolAcre, no una prueba RFC 8785. Si la segunda matriz fuera `["pack","cut"]`, las claves de clasificación dejarían visible esa diferencia correctamente porque cambiar la matriz cambiaría la secuencia representada.
Lo que esto no cubre
La clasificación de claves no define una igualdad profunda para cada aplicación. Los nombres duplicados son aceptados por `JSON.parse`, que mantiene el último valor, por lo que el formato puede borrar la evidencia de que una fuente contenía repeticiones. Es posible que los números enteros grandes ya hayan perdido precisión en el valor de JavaScript. Un dominio también puede tratar los arreglos seleccionados como conjuntos, pero ToolAcre no puede inferir esa regla y, por lo tanto, nunca reordena los arreglos.
El formateador tampoco compara esquemas, aplica valores predeterminados, normaliza Unicode ni decide si dos representaciones numéricas son aceptables para un sistema posterior. Esos son contratos separados. Utilice el formato para reducir el ruido de la presentación, una comparación estructural especialmente diseñada para la igualdad de valores y el canonicalizador especificado para bytes exactos. Mezclar esos trabajos bajo la palabra “normalizar” crea una falsa confianza sobre lo que realmente se comparó.
Conclusión: el orden es insignificante para el modelo y significativo para los bytes
El orden de los miembros del objeto no tiene significado en el modelo de datos RFC 8259, mientras que el orden de la matriz sí. Los bytes de origen aún registran tanto el orden como los espacios en blanco, por lo que los hash, las firmas y las diferencias de texto observan distinciones que una comparación orientada a valores puede ignorar. Indique qué capa importa antes de elegir una herramienta: la identidad textual, la equivalencia de valores analizados y la identidad canónica definida por protocolo son tres preguntas diferentes.
ToolAcre admite los dos primeros flujos de trabajo solo indirectamente: el formato consistente aclara las diferencias textuales y la clasificación alfabética recursiva de claves de objetos puede hacer que las comparaciones humanas sean más silenciosas. Las matrices nunca se ordenan. El resultado no es RFC 8785 canónico JSON y no debe firmarse como si lo fuera. Conserve la entrada original cuando la evidencia léxica sea importante, especialmente porque el análisis de claves duplicadas conserva solo el último valor.