Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes. It also provides a method that returns sorted object strings that can be used for object comparison without hashes. One of the fastest among other analogues (see benchmarks).
Hashes are built on top of node's crypto module. If you want to use it in browser it's recommented to use objectSorter only. It will provide you with unique string representation of your object. Afterwards you may use some hash library to reduce string size. Also you may use something like browserify-crypto or some kind of crypto functions polyfills.
- node-object-hash
Disclaimer: No new features or changes that may break hashes from previous versions. There's no need to update unless you're starting project from scratch.
- Refactor and migration to typescript 5.
- Drop old node support.
- Removed typescript namespaces.
- Updated exported functions and object structure.
- Removed faker and old benchmarks.
- New CI and release automation.
- Library rewritten in typescript that could cause some side-effects, but it should not.
- With
coerce=falseSets will no longer generate the same hashes asArrays. In order to restore previous behavior setcoerce.set=true. - With
coerce=falseSymbols will generate hash based on symbol.toStringvalue. That's useful forSymbol.for('smth'). Ifcoerce.symbol=trueallSymbolss will have equal hashes. TLDR; If you use library withSets orSymbols withcoerce=falsein order to keep hashes the same as inv1.X.Xyou should use following constructor:
const hasher = require('node-object-hash')({coerce: {set: true, symbol: true}})
- Object sorter sources moved to
distdirectory. If you required it directly viarequire('node-object-hash/objectSorter')you should change it to require('node-object-hash/dist/objectSorter'). - Removed old
v0version from code. - Changed license to MIT.
- New granular options. Now you can specify what types need to be sorted or coerced.
- Add new
trimoption. It can be used to remove unncecessary spaces instrings orfunctionbodies. - Library rewritten to typescript, so it may have better ts compatibility.
npm i node-object-hash -S
- Supports object property sorting for constant hashes for objects with same properties, but different order.
- Supports ES6 Maps and Sets.
- Supports type coercion (see table below).
- Supports all hashes and encodings of crypto library.
- Supports large objects and arrays.
- Has granular options that allows to control what should be sorted or coerced.
- Very fast comparing to other libs (see Benchmarks section).
This map displays what types will have identical string representation (e.g. new Set([1, 2, 3]) and [1, 2, 3] will have equal string representations and hashes.
| Initial type | Mapped type |
|---|---|
| Array ([]) | array |
| ArrayObject (new Array()) | |
| Int8Array | |
| Uint8Array | |
| Uint8ClampedArray | |
| Int16Array | |
| Uint16Array | |
| Int32Array | |
| Uint32Array | |
| Float32Array | |
| Float64Array | |
| Buffer | |
| Set | |
| Map | array[array] |
| string ('') | string |
| String (new String()) | |
| boolean (true) | boolean |
| Boolean (new Boolean()) | |
| number (true) | number |
| Number (new Number()) | |
| Date | date |
| Symbol | symbol |
| undefined | undefined |
| null | null |
| function | function |
| Object ({}) | object |
| Object (new Object()) | |
| other | unknown |
| Initial "type" | Coerced type | Example |
|---|---|---|
| boolean | string | true -> 1 |
| number | string | '1' -> 1 |
| string | string | 'a' -> a |
| null | string (empty) | null -> |
| undefined | string (empty) | undefined -> |
See changelog For v2 changes see changelog-v2
Full API docs could be found in docs.
require('node-object-hash').hasher([options]);Returns preconfigured object with API
Parameters:
options:object- object with hasher config optionsoptions.coerce:boolean|object- if true performs type coercion (default:true); e.g.hash(true) == hash('1') == hash(1),hash(false) == hash('0') == hash(0)options.sort:boolean|object- if true performs sorting on objects, arrays, etc. (default:true); in order to perform sorting onTypedArray(Buffer,Int8Array, etc.), specify it explicitly:typedArray: trueoptions.trim:boolean|object- if true performs trim of spaces and replaces space-like characters with single space (default:false);options.alg:string- sets default hash algorithm (default:'sha256'); can be overridden inhashmethod;options.enc:string- sets default hash encoding (default:'hex'); can be overridden inhashmethod;
Returns hash string.
object:*object for calculating hash;options:objectobject with options;options.alg:string- hash algorithm (default:'sha256');options.enc:string- hash encoding (default:'hex');
Returns sorted string generated from object (can be used for object comparison)
object:*- object for sorting;
In order to serialize and hash your custom objects you may provide .toHashableString() method for your object. It should return string that will be hashed. You may use objectSorter and pass notable fields to it in your .toHashableString method.
For typescript users you may add to your classes implements Hashable.
>=nodejs-0.10.0
>=nodejs-6.0.0>=nodejs-4.0.0(requires to run node with--harmonyflag)
var { hasher } = require('node-object-hash');
var hashSortCoerce = hasher({ sort: true, coerce: true });
// or
// var hashSortCoerce = hasher();
// or
// var hashSort = hasher({sort:true, coerce:false});
// or
// var hashCoerce = hasher({sort:false, coerce:true});
var objects = {
a: {
a: [{ c: 2, a: 1, b: { a: 3, c: 2, b: 0 } }],
b: [1, 'a', {}, null],
},
b: {
b: ['a', 1, {}, undefined],
a: [{ c: '2', b: { b: false, c: 2, a: '3' }, a: true }],
},
c: ['4', true, 0, 2, 3],
};
hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
// returns true
hashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'For more examples you can see tests or try it out online at runkit
Bench data - array of 100000 complex objects
npm run benchto run custom benchmarknpm run benchmarkto run benchmark suitenpm run benchmark:hashto run hash benchmark suite
| Hashing algorithm | Result hash bytes length | Performance (ops/sec) |
|---|---|---|
sha256 (default) |
64 | 1,599 +- 5.77% |
sha1 |
40 | 1,983 +- 1.50% |
sha224 |
56 | 1,701 +- 2.81% |
sha384 |
96 | 1,800 +- 0.81% |
sha512 |
128 | 1,847 +- 1.75% |
md4 |
32 | 1,971 +- 0.98% |
md5 |
32 | 1,691 +- 3.18% |
whirlpool |
128 | 1,487 +- 2.33% |
Custom benchmark (code)
| Library | Time (ms) | Memory (Mb) |
|---|---|---|
| node-object-hash-0.2.1 | 5813.575 | 34 |
| node-object-hash-1.0.X | 2805.581 | 27 |
| node-object-hash-1.1.X (node v7) | 2555.583 | 27 |
| node-object-hash-1.2.X (node v7) | 2390.752 | 28 |
| node-object-hash-2.X.X (node v12) | 1990.622 | 24 |
| object-hash-1.1.5 (node v7) | 28115.553 | 39 |
| object-hash-1.1.4 | 534528.254 | 41 |
| object-hash-1.1.3 | ERROR | Out of heap memory |
| hash-object-0.1.7 | 9219.826 | 42 |
Benchmark suite module (code)
| Library (node v12) | Perf (ops/s) |
|---|---|
| node-object-hash-2.0.0 | 2087 ±0.59% |
| object-hash-1.3.1 | 239 ±0.39% |
| hash-object-0.1.7 | 711 ±0.18% |
- object-hash - Slow, useful for browsers because it not uses node's crypto library
- hash-object - no ES6 types support
MIT