A pure Elixir implementation of RFC 8785: JSON Canonicalization Scheme (JCS).
JCS can be used to establish a canonical deterministic representation of linked JSON data. These represenations can then be used in establishing identity proofs.
For an example, see the W3C Data Integrity 1.0 report.
That report also gives as an example usage identity proofs, the ability to authenticate as an entity identified by a Decentralized Identifier (DID).
The JSON encoding here is probably orders of magnitude slower than the Jason library. There is no attempt here to decent better memory management in building the output, and sorting object properties based on their UTF-16-encoded keys can probably be greatly improved also.
Pull requests are gratefully encouraged!
Code is based on the Python 3 jcs package.
Test suites are from the Java implementation by Samuel Erdtman and from Appendix B of RFC 8785.
If available in Hex, the package can be installed
by adding jcs
to your list of dependencies in mix.exs
:
def deps do
[
{:jcs, "~> 0.1.1"}
]
end
Jcs.encode(%{"aa" => 200, "b" => 100.0, "西葛西駅" => [200, "station"], "a" => "hello\tworld!"})
"{\"a\":\"hello\\tworld!\",\"aa\":200,\"b\":100,\"西葛西駅\":[200,\"station\"]}"
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/jcs.
This library depends on using the Ryu algorithm that was added to Erlang
in OTP 25, via the :erlang.float_to_binary/2
function and the new :short
option. See https://www.erlang.org/blog/my-otp-25-highlights/#new-option-short-for-erlangfloat_to_list2-and-erlangfloat_to_binary2 for
more information.
Also note that while the RFC states that the Ryu algorithm is compliant for encoding floats, the Erlang implementation encodes integral values like 1e+23 as "1.0e23", where as RFC 8785 would encode this as "1e+23".
When attempting to handle all the test cases in the RFC appendix, it appears as though not all of the IEEE754 double value examples are able to be encoded into Elixir floats. These are commented out as "Elixir can not set this value" in the JcsNumbersTest test module.