Zero Signup ToolsFree browser tools

Developer Tools

JSON Canonicalizer

Canonicalize JSON using RFC 8785 (JCS) in your browser. Sort keys, normalize numbers, minimal string escapes, plus a SHA-256 of the canonical bytes.

Mode

Single canonicalizes one document. Compare canonicalizes two documents side by side so you can prove they are (or are not) semantically equal.

Samples

Input JSON

Canonical JSON (RFC 8785)

129 bytes
{"Title":"My Release","amount":1,"audience":null,"balance":0,"count":1000,"deleted":false,"id":"abc","tag":"release","version":2}

SHA-256 of the canonical UTF-8 bytes

computing...

This is the digest you would HMAC or sign for cryptographic proofs. Two semantically equal documents always produce the same SHA-256.

Base64 of the canonical bytes

eyJUaXRsZSI6Ik15IFJlbGVhc2UiLCJhbW91bnQiOjEsImF1ZGllbmNlIjpudWxsLCJiYWxhbmNlIjowLCJjb3VudCI6MTAwMCwiZGVsZXRlZCI6ZmFsc2UsImlkIjoiYWJjIiwidGFnIjoicmVsZWFzZSIsInZlcnNpb24iOjJ9

7 canonical rewrites

  • Object members were reordered by UTF-16 code unit.

    keys: version,amount,count,deleted,tag,Title,balance,id,audience keys: Title,amount,audience,balance,count,deleted,id,tag,version

  • Number was re-rendered using the ECMA-262 ToString algorithm (the form JCS requires).

    1.0 1

  • Number was re-rendered using the ECMA-262 ToString algorithm (the form JCS requires).

    1e3 1000

  • Number was re-rendered using the ECMA-262 ToString algorithm (the form JCS requires).

    -0 0

  • String was re-escaped using the RFC 8785 minimal escape set.

    "version" "release"

  • String was re-escaped using the RFC 8785 minimal escape set.

    "amount" "My Release"

  • String was re-escaped using the RFC 8785 minimal escape set.

    "count" "abc"

What the RFC 8785 rules actually say

1. Member ordering

Object members are emitted in ascending order of the key string, compared as sequences of UTF-16 code units. This is the same ordering as the default String comparison in JavaScript.

2. Number normalization

Numbers are emitted using ECMA-262 ToString. So 1e3 becomes 1000, 1.0 becomes 1, and -0 becomes 0. NaN and Infinity are rejected.

3. String escaping

Only six named escapes (\" \\ \b \f \n \r \t) and \u00XX for control characters U+0000 to U+001F without a named escape. Everything else, including non-ASCII and surrogate pairs, is emitted as-is.

4. No whitespace

Tokens are emitted with no whitespace between them. Arrays preserve their element order; only object members are reordered.

Reference: RFC 8785 (March 2020), JSON Canonicalization Scheme (JCS), IETF Network Working Group. Compatible with the JCS test vectors and with output produced by jcs.js, the cyberphone Java JCS library, and canonicaljson-go.

How to use

  1. Paste a JSON value (object, array, or any scalar) into the input. The five sample buttons demonstrate key reordering, number normalization, Unicode keys, signed-webhook style payloads, and control character escaping.
  2. Read the Canonical JSON output: it is the exact byte sequence RFC 8785 produces for your input. Copy it for use with a signing library.
  3. Use the SHA-256 of the canonical UTF-8 bytes when you need to HMAC, fingerprint, or sign the document. Two semantically equal documents always produce the same hash.
  4. Open the rewrites panel to see what changed: which keys were reordered, which numbers were re-rendered with ECMA-262 ToString, and which strings were re-escaped under the minimal RFC 8785 escape set.
  5. Switch to Compare two and paste a second document to verify that a payload re-serialized elsewhere still canonicalizes to the same bytes and the same SHA-256. The status pill shows equal or not equal at a glance.

About this tool

JSON Canonicalizer produces the single deterministic byte sequence that the IETF JSON Canonicalization Scheme (RFC 8785, March 2020) defines for any JSON value. The output is intended as the exact bytes you feed into a signing or hashing function, so two producers that emit semantically equal JSON always agree on the bytes they sign. The implementation follows the four RFC 8785 rules: object members are emitted in ascending order by UTF-16 code unit (the same ordering as a default JavaScript string sort, applied recursively to every nested object); numeric values are emitted using the ECMA-262 Number-to-String algorithm so 1e3 becomes 1000, 1.0 becomes 1, 100.0 becomes 100, -0 becomes 0, and NaN/Infinity are rejected (JSON does not allow them anyway); strings use the minimal RFC 8259 escape set, namely the six named escapes for double quote, backslash, backspace, form feed, line feed, carriage return, and tab, plus the six-character \u00XX form for the remaining control characters U+0000 to U+001F, while every other code point (including non-ASCII like CJK ideographs, accented Latin, and emoji surrogate pairs) is emitted verbatim and ends up as its UTF-8 bytes in the byte output; and no whitespace is emitted between tokens. Once the canonical string is built it is encoded as UTF-8, the byte count is shown, and a SHA-256 of those bytes is computed via the browser SubtleCrypto API. That SHA-256 is the value you would HMAC for a webhook proof or sign with an Ed25519 / ECDSA key for content-addressed storage, Sigstore-style attestations, Verifiable Credentials Data Integrity proofs, or JOSE/COSE detached signatures. A Compare two mode canonicalizes a pair of documents side by side and reports whether the canonical bytes match, which is the fastest way to confirm that a payload re-serialized by another library is still byte-identical for signing. An audit panel highlights every rewrite the canonicalizer applied: keys reordered, number literals normalized, strings re-escaped, so you can teach the difference between a casual JSON dump and a canonical one without leaving the page. All work runs in the browser; no input is uploaded.

Free to use. Works in your browser. No signup, no login.

Related tools

You may also like

All tools
All toolsDeveloper Tools