Created
October 25, 2016 23:25
-
-
Save shanewholloway/c0b5a2118025b531b0da37ab9930bc9d to your computer and use it in GitHub Desktop.
JSON hashing, canonicalization, digests, SHA, MD5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function json_canonical(obj) { | |
return JSON.stringify(obj, (key, value) => { | |
if ('object' !== typeof value) | |
return value // it is a value of some kind | |
if (value instanceof Array) | |
return value // Arrays are (already) ordered | |
// normalize into new object initializing via sorted keys | |
let result = {} | |
for(let k of Object.keys(value).sort()) | |
result[k] = value[k] | |
return result }) } | |
function json_hash(obj, hash_algorithm='sha1') { | |
let src_json = json_canonical(obj) | |
let hash = crypto.createHash(hash_algorithm) | |
.update(src_json, 'utf8') | |
hash.src_json = src_json | |
return hash } | |
function json_digest(obj, encoding='hex', hash_algorithm='sha1') { | |
return json_hash(obj, hash_algorithm).digest(encoding) } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const assert = require('assert') | |
let {json_digest, json_canonical} = require('./json_hashing') | |
class MyClass { toJSON() { return {lst: [1,2,3], msg: 'was here'} }} | |
let myObj = new MyClass() | |
let ans = [ | |
{b: 'bee', c: myObj, a: {z: 'zzeee', d: 'ddeeee'}}, | |
{b: 'bee', a: {z: 'zzeee', d: 'ddeeee'}, c: myObj}, | |
{a: {z: 'zzeee', d: 'ddeeee'}, c: myObj, b: 'bee'}, | |
{a: {d: 'ddeeee', z: 'zzeee'}, c: myObj, b: 'bee'}, | |
].map(e => json_digest(e)) | |
assert.deepEqual(ans, [ | |
'316944236441fe58d5ad02c5d494ffef284657f8', | |
'316944236441fe58d5ad02c5d494ffef284657f8', | |
'316944236441fe58d5ad02c5d494ffef284657f8', | |
'316944236441fe58d5ad02c5d494ffef284657f8']) | |
assert.equal(ans.reduce((k,v) => k==v ? k : null), | |
'316944236441fe58d5ad02c5d494ffef284657f8') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment