Created
February 20, 2015 19:40
-
-
Save cmawhorter/690b87b97bc6bf818bd0 to your computer and use it in GitHub Desktop.
Deep complex object fingerprinting/hashing in nodejs javascript (recursive).
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
| var crypto = require('crypto'); | |
| var ALGO = 'sha256'; | |
| function hashValue(val) { | |
| var hash = crypto.createHash(ALGO) | |
| , target; | |
| switch (toString.call(val)) { | |
| case '[object Object]': | |
| target = hashObject(val); | |
| break; | |
| case '[object Array]': | |
| target = hashArray(val); | |
| break; | |
| default: | |
| target = JSON.stringify(val); | |
| break; | |
| } | |
| // console.log('hashValue', val, target); | |
| return hash.update(target).digest('hex'); | |
| } | |
| function hashObject(obj) { | |
| var hash = crypto.createHash(ALGO) | |
| , keys = Object.keys(obj || {}); | |
| keys.sort(); // order of hash/dict is not guaranteed, so we do alpha | |
| for (var i=0; i < keys.length; i++) { | |
| var key = keys[i] | |
| , val = obj[key] | |
| , signature = hashValue(val); | |
| // console.log('signing - %s: %s => %s', key, val, signature); | |
| hash.update(key); | |
| hash.update(signature); | |
| } | |
| return hash.digest('hex'); | |
| } | |
| function hashArray(arr) { | |
| var hash = crypto.createHash(ALGO); | |
| hash.setEncoding('hex'); | |
| // FIXME: this probably needs some improvement. i didn't want to just simply | |
| // use arr.length, but if arr order changes the hash won't match | |
| arr.sort(); | |
| for (var i=0; i < arr.length; i++) { | |
| var val = arr[i]; | |
| hash.update(hashValue(val)); | |
| } | |
| return hash.read(); | |
| } | |
| module.exports = function(obj) { | |
| return hashValue(obj); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment