UNPKG

15.8 kBMarkdownView Raw
1# node-object-hash
2
3Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes.
4It also provides a method that returns sorted object strings that can be used for object comparison without hashes.
5One of the fastest among other analogues (see [benchmarks](#Benchmarks)).
6
7Hashes are built on top of node's crypto module
8(so for using in browser use something like [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify) or some kind of crypto functions polyfills). Or you can use only `objectSorter` ([source](https://github.com/SkeLLLa/node-object-hash/blob/master/objectSorter.js)) for getting your objects' string representation and compare or pass them to your own hash function.
9
10[![node](https://img.shields.io/node/v/node-object-hash.svg?maxAge=21600&style=flat-square)]()
11[![NPM](https://img.shields.io/npm/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/packages/node-object-hash)
12[![NPM Downloads](https://img.shields.io/npm/dt/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/packages/node-object-hash)
13[![Build Status](https://img.shields.io/travis/SkeLLLa/node-object-hash.svg?maxAge=21600&branch=master&style=flat-square)](https://travis-ci.org/SkeLLLa/node-object-hash)
14[![Known Vulnerabilities](https://snyk.io/test/github/SkeLLLa/node-object-hash/badge.svg?maxAge=21600&style=flat-square)](https://snyk.io/test/github/skellla/node-object-hash)
15[![Code Climate](https://img.shields.io/codeclimate/github/SkeLLLa/node-object-hash.svg?maxAge=21600&style=flat-square)](https://codeclimate.com/github/SkeLLLa/node-object-hash/code)
16[![Coverage](https://img.shields.io/codeclimate/coverage/github/SkeLLLa/node-object-hash.svg?maxAge=21600&style=flat-square)](https://codeclimate.com/github/SkeLLLa/node-object-hash/coverage)
17[![Analytics](https://ga-beacon.appspot.com/UA-90571586-1/node-object-hash/readme?pixel&useReferer)](https://github.com/igrigorik/ga-beacon)
18
19# Installation
20
21`npm i node-object-hash -S`
22
23# Features
24- Supports object property sorting for constant hashes for objects with same properties, but different order.
25- Supports ES6 (Weak)Maps and (Weak)Sets.
26- Supports type coercion (e.g. 1 and "1" will be the same)
27 - rules:
28 - numbers and strings represented without quotes;
29 - boolean values converted to numbers;
30- Supports all hashes and encodings of crypto library
31- Supports large objects and arrays
32- Very fast comparing to other libs (see [Benchmarks](#Benchmarks) section)
33
34# Changes
35
36## v0.x.x -> v1.0.0
37
38- Sorting mechanism rewritten form ES6 Maps to simple arrays
39 (add <=node-4.0.0 support)
40- Performance optimization (~2 times faster than 0.x.x)
41- API changes:
42 - Now module returns 'constructor' function, where you can set
43 default parameters: ```var objectHash = require('node-object-hash')(options);```
44
45In case if you still need an old 0.x.x version it's available in `hash.js`
46file.
47
48## v1.0.X -> v1.1.X
49
50Mainly all changes affected codestyle and documentation to provide better
51experience using this library. There are no changes that should affect
52functionality.
53
54- Renamed `sortObject` function to `sort` (old one is still present in code
55for backward compatibility).
56- Performed some refactoring for better codestyle and documentation.
57- Old version (`0.X.X`) moved to subfolder (`./v0`).
58- Advanced API reference added: [link](#Full API docs).
59
60# API overview
61
62## Constructor `require('node-object-hash')([options])`
63
64Returns preconfigured object with API
65
66Parameters:
67* `options`:`object` - object with hasher config options
68* `options.coerce`:`boolean` - if true performs type coercion (default: `true`);
69e.g. `hash(true) == hash('1') == hash(1)`, `hash(false) == hash('0') == hash(0)`
70* `options.sort`:`boolean` - if true performs sorting on objects, arrays, etc. (default: `true`);
71* `options.alg`:`string` - sets default hash algorithm (default: `'sha256'`); can be overridden in `hash` method;
72* `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;
73
74## API methods
75
76### `hash(object[, options])`
77
78Returns hash string.
79* `object`:`*` object for calculating hash;
80* `options`:`object` object with options;
81* `options.alg`:`string` - hash algorithm (default: `'sha256'`);
82* `options.enc`:`string` - hash encoding (default: `'hex'`);
83
84### `sort(object)`
85
86Returns sorted string generated from object (can be used for object comparison)
87* `object`:`*` - object for sorting;
88
89# Full API docs
90
91## Modules
92
93<dl>
94<dt><a href="#module_node-object-hash/objectSorter">node-object-hash/objectSorter</a> : <code><a href="#module_node-object-hash/objectSorter..makeObjectSorter..objectToString">objectToString</a></code></dt>
95<dd><p>Object sorter module.
96It provides object sorter function constructor.</p>
97</dd>
98<dt><a href="#module_node-object-hash">node-object-hash</a> : <code><a href="#module_node-object-hash..apiConstructor">apiConstructor</a></code></dt>
99<dd><p>Node object hash module.
100It provides a methods that return object hash or sorted object string.</p>
101</dd>
102</dl>
103
104<a name="module_node-object-hash/objectSorter"></a>
105
106## node-object-hash/objectSorter : <code>[objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)</code>
107Object sorter module.
108It provides object sorter function constructor.
109
110
111* [node-object-hash/objectSorter](#module_node-object-hash/objectSorter) : <code>[objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)</code>
112 * [~_guessObjectType(obj)](#module_node-object-hash/objectSorter.._guessObjectType) ⇒ <code>string</code>
113 * [~_guessType(obj)](#module_node-object-hash/objectSorter.._guessType) ⇒ <code>string</code>
114 * [~makeObjectSorter([options])](#module_node-object-hash/objectSorter..makeObjectSorter) ⇒ <code>[objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)</code>
115 * [~objectToString(obj)](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString) ⇒ <code>string</code>
116
117<a name="module_node-object-hash/objectSorter.._guessObjectType"></a>
118
119### node-object-hash/objectSorter~_guessObjectType(obj) ⇒ <code>string</code> ℗
120Guesses object's type
121
122**Kind**: inner method of <code>[node-object-hash/objectSorter](#module_node-object-hash/objectSorter)</code>
123**Returns**: <code>string</code> - Object type
124**Access:** private
125
126| Param | Type | Description |
127| --- | --- | --- |
128| obj | <code>Object</code> | Object to guess type |
129
130**Example**
131```js
132var a = [];
133_guessObjectType(a) === 'array'; // true
134```
135<a name="module_node-object-hash/objectSorter.._guessType"></a>
136
137### node-object-hash/objectSorter~_guessType(obj) ⇒ <code>string</code> ℗
138Guesses variable type
139
140**Kind**: inner method of <code>[node-object-hash/objectSorter](#module_node-object-hash/objectSorter)</code>
141**Returns**: <code>string</code> - Variable type
142**Access:** private
143
144| Param | Type | Description |
145| --- | --- | --- |
146| obj | <code>\*</code> | Variable to guess type |
147
148**Example**
149```js
150var a = '';
151_guessType(a) === 'string'; // true
152```
153<a name="module_node-object-hash/objectSorter..makeObjectSorter"></a>
154
155### node-object-hash/objectSorter~makeObjectSorter([options]) ⇒ <code>[objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)</code> ℗
156Creates object sorter function
157
158**Kind**: inner method of <code>[node-object-hash/objectSorter](#module_node-object-hash/objectSorter)</code>
159**Returns**: <code>[objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)</code> - Object sorting function
160**Access:** private
161
162| Param | Type | Default | Description |
163| --- | --- | --- | --- |
164| [options] | <code>Object</code> | | Sorter options |
165| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
166| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
167
168**Example**
169```js
170// with coercion
171var sorter = makeObjectSorter({coerce: true, sort: false});
172sorter(1) === "1"; // true
173// with sort
174var sorter = makeObjectSorter({coerce: false, sort: true});
175sorter([2, 3, 1]) === [1, 2, 3]; // true
176```
177<a name="module_node-object-hash/objectSorter..makeObjectSorter..objectToString"></a>
178
179#### makeObjectSorter~objectToString(obj) ⇒ <code>string</code> ℗
180Object sorting function
181
182**Kind**: inner method of <code>[makeObjectSorter](#module_node-object-hash/objectSorter..makeObjectSorter)</code>
183**Returns**: <code>string</code> - Sorted string
184**Access:** private
185
186| Param | Type | Description |
187| --- | --- | --- |
188| obj | <code>Object</code> | Object to sort |
189
190<a name="module_node-object-hash"></a>
191
192## node-object-hash : <code>[apiConstructor](#module_node-object-hash..apiConstructor)</code>
193Node object hash module.
194It provides a methods that return object hash or sorted object string.
195
196
197* [node-object-hash](#module_node-object-hash) : <code>[apiConstructor](#module_node-object-hash..apiConstructor)</code>
198 * _instance_
199 * [.sort(obj)](#module_node-object-hash+sort) ⇒ <code>string</code>
200 * [.hash(obj, [opts])](#module_node-object-hash+hash) ⇒ <code>string</code>
201 * _inner_
202 * [~apiConstructor([options])](#module_node-object-hash..apiConstructor) ⇒ <code>[API](#module_node-object-hash..API)</code>
203 * [~API](#module_node-object-hash..API) : <code>Object</code>
204
205<a name="module_node-object-hash+sort"></a>
206
207### node-object-hash.sort(obj) ⇒ <code>string</code>
208Creates sorted string from given object
209
210**Kind**: instance method of <code>[node-object-hash](#module_node-object-hash)</code>
211**Returns**: <code>string</code> - Sorted object string
212**Access:** public
213**See**: [objectToString](#module_node-object-hash/objectSorter..makeObjectSorter..objectToString)
214
215| Param | Type | Description |
216| --- | --- | --- |
217| obj | <code>\*</code> | JS object to be sorted |
218
219**Example**
220```js
221var apiConstructor = require('node-object-hash');
222var sorter = apiConstructor({sort:true, coerce:true}).sort;
223
224sort({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
225// "{a:[1,3,5],b:{b:1,d:x},c:2}"
226```
227<a name="module_node-object-hash+hash"></a>
228
229### node-object-hash.hash(obj, [opts]) ⇒ <code>string</code>
230Creates hash from given object
231
232**Kind**: instance method of <code>[node-object-hash](#module_node-object-hash)</code>
233**Returns**: <code>string</code> - Object hash value
234**Access:** public
235
236| Param | Type | Default | Description |
237| --- | --- | --- | --- |
238| obj | <code>\*</code> | | JS object to hash |
239| [opts] | <code>Object</code> | | Options |
240| [opts.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Crypto algorithm to use |
241| [opts.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding |
242
243**Example**
244```js
245var apiConstructor = require('node-object-hash');
246var hasher = apiConstructor({sort:true, coerce:true}).hash;
247
248hash({b: {b: 1, d: 'x'}, c: 2, a: [3, 5, 1]});
249// "4c18ce0dcb1696b329c8568d94a9830da810437d8c9e6cecf5d969780335a26b"
250```
251<a name="module_node-object-hash..apiConstructor"></a>
252
253### node-object-hash~apiConstructor([options]) ⇒ <code>[API](#module_node-object-hash..API)</code>
254Generates node-object-hash API object
255
256**Kind**: inner method of <code>[node-object-hash](#module_node-object-hash)</code>
257**Returns**: <code>[API](#module_node-object-hash..API)</code> - Node object hash API instance
258
259| Param | Type | Default | Description |
260| --- | --- | --- | --- |
261| [options] | <code>Object</code> | | Library options |
262| [options.coerce] | <code>boolean</code> | <code>true</code> | Performs type coercion |
263| [options.sort] | <code>boolean</code> | <code>true</code> | Performs array, object, etc. sorting |
264| [options.alg] | <code>string</code> | <code>&quot;sha256&quot;</code> | Default crypto algorithm to use (can be overridden) |
265| [options.enc] | <code>string</code> | <code>&quot;hex&quot;</code> | Hash string encoding (can be overridden) |
266
267**Example**
268```js
269var apiConstructor = require('node-object-hash');
270var hashSortCoerce = apiConstructor({sort:true, coerce:true});
271// or
272var hashSort = apiConstructor({sort:true, coerce:false});
273// or
274var hashCoerce = apiConstructor({sort:false, coerce:true});
275
276var objects = {
277 a: {
278 a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
279 b: [1, 'a', {}, null],
280 },
281 b: {
282 b: ['a', 1, {}, undefined],
283 a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
284 },
285 c: ['4', true, 0, 2, 3]
286};
287hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
288// returns true
289
290hashSortCoerce.sort(object.c);
291// returns '[0,1,2,3,4]'
292```
293<a name="module_node-object-hash..API"></a>
294
295### node-object-hash~API : <code>Object</code>
296Node object hash API object
297
298**Kind**: inner typedef of <code>[node-object-hash](#module_node-object-hash)</code>
299**Properties**
300
301| Name | Type | Description |
302| --- | --- | --- |
303| hash | <code>function</code> | Returns object hash string (see [hash](#module_node-object-hash+hash)) |
304| sort | <code>function</code> | Returns sorted object string (see [sort](#module_node-object-hash+sort)) |
305
306
307# Requirements
308
309## version \>=1.0.0
310- `>=nodejs-0.10.0`
311
312## version \>=0.1.0 && <1.0.0
313- `>=nodejs-6.0.0`
314- `>=nodejs-4.0.0` (requires to run node with `--harmony` flag)
315
316## browsers
317- nodejs `crypto` module for browsers (e.g. [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify)).
318
319# Example
320```js
321var hasher = require('node-object-hash');
322
323var hashSortCoerce = hasher({sort:true, coerce:true});
324// or
325// var hashSortCoerce = hasher();
326// or
327// var hashSort = hasher({sort:true, coerce:false});
328// or
329// var hashCoerce = hasher({sort:false, coerce:true});
330
331var objects = {
332 a: {
333 a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
334 b: [1, 'a', {}, null],
335 },
336 b: {
337 b: ['a', 1, {}, undefined],
338 a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
339 },
340 c: ['4', true, 0, 2, 3]
341};
342
343hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
344// returns true
345
346hashSortCoerce.sort(object.c);
347// returns '[0,1,2,3,4]'
348```
349
350For more examples you can see [tests file](https://github.com/SkeLLLa/node-object-hash/blob/master/test/hash2.js)
351or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)
352
353# Benchmarks
354
355Bench data - array of 100000 complex objects
356
357## Usage
358
359* `npm run bench` to run custom benchmark
360* `npm run bench2` to run benchmark suite
361
362## Results
363
364### Custom benchmark ([code](bench/index.js))
365
366| Library | Time (ms) | Memory (Mb) |
367|---------------------------------------|------------|--------------------|
368| node-object-hash-0.2.1 | 5813.575 | 34 |
369| node-object-hash-1.0.X | 2805.581 | 27 |
370| node-object-hash-1.1.X (node v7) | 2555.583 | 27 |
371| object-hash-1.1.5 (node v7) | 28115.553 | 39 |
372| object-hash-1.1.4 | 534528.254 | 41 |
373| object-hash-1.1.3 | ERROR | Out of heap memory |
374| hash-object-0.1.7 | 9219.826 | 42 |
375
376### Benchmark suite module ([code](bench/bench.js))
377
378```
379 node-object-hash x 844 ops/sec ±2.51% (82 runs sampled)
380 node-object-hash-v0 x 540 ops/sec ±1.34% (82 runs sampled)
381 hash-object x 310 ops/sec ±0.88% (81 runs sampled)
382 object-hash x 107 ops/sec ±1.66% (72 runs sampled)
383```
384
385## Links
386
387* https://www.npmjs.com/package/object-hash (Slow, useful for browsers because it not uses node's crypto library)
388* https://www.npmjs.com/package/hash-object (no ES6 types support)
389
390# License
391
392ISC