README.hbs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # node-object-hash
  2. Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes.
  3. It also provides a method that returns sorted object strings that can be used for object comparison without hashes.
  4. One of the fastest among other analogues (see [benchmarks](#benchmarks)).
  5. Hashes are built on top of node's crypto module
  6. (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.
  7. [![node](https://img.shields.io/node/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://nodejs.org/download/release/latest)[![NPM](https://img.shields.io/npm/v/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![NPM Downloads](https://img.shields.io/npm/dt/node-object-hash.svg?maxAge=21600&style=flat-square)](https://npmjs.org/package/node-object-hash)[![npms.io Score](https://badges.npms.io/node-object-hash.svg?style=flat-square)](https://npms.io/search?q=node-object-hash)[![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)[![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)[![Coverage](https://api.codeclimate.com/v1/badges/199467889caf98d59690/test_coverage)](https://codeclimate.com/github/SkeLLLa/node-object-hash/test_coverage)[![Maintainability](https://api.codeclimate.com/v1/badges/199467889caf98d59690/maintainability)](https://codeclimate.com/github/SkeLLLa/node-object-hash/maintainability)[![Inline docs](http://inch-ci.org/github/SkeLLLa/node-object-hash.svg?branch=master&style=flat-square)](http://inch-ci.org/github/SkeLLLa/node-object-hash)[![Analytics](https://ga-beacon.appspot.com/UA-90571586-1/node-object-hash?pixel&useReferer)](https://github.com/igrigorik/ga-beacon)
  8. # Installation
  9. `npm i node-object-hash -S`
  10. # Features
  11. - Supports object property sorting for constant hashes for objects with same properties, but different order.
  12. - Supports ES6 Maps and Sets.
  13. - Supports type coercion (see table below)
  14. - Supports all hashes and encodings of crypto library
  15. - Supports large objects and arrays
  16. - Very fast comparing to other libs (see [Benchmarks](#benchmarks) section)
  17. ## Type map
  18. This map displays what types will have identical string representation (e.g. new Set([1, 2, 3]) and [1, 2, 3] will have
  19. equal string representations and hashes.
  20. | Initial type | Mapped type |
  21. |---------------------------|--------------|
  22. | Array ([]) | array |
  23. | ArrayObject (new Array()) | |
  24. | Int8Array | |
  25. | Uint8Array | |
  26. | Uint8ClampedArray | |
  27. | Int16Array | |
  28. | Uint16Array | |
  29. | Int32Array | |
  30. | Uint32Array | |
  31. | Float32Array | |
  32. | Float64Array | |
  33. | Buffer | |
  34. | Set | |
  35. | | |
  36. | Map | array[array] |
  37. | | |
  38. | string ('') | string | string |
  39. | String (new String()) | |
  40. | | |
  41. | boolean (true) | boolean |
  42. | Boolean (new Boolean()) | |
  43. | | |
  44. | number (true) | number |
  45. | Number (new Number()) | |
  46. | | |
  47. | Date | date |
  48. | | |
  49. | Symbol | symbol |
  50. | | |
  51. | undefined | undefined |
  52. | | |
  53. | null | null |
  54. | | |
  55. | function | function |
  56. | | |
  57. | Object ({}) | object |
  58. | Object (new Object()) | |
  59. | | |
  60. | other | unknown |
  61. ## Coercion map
  62. | Initial "type" | Coerced type | Example |
  63. |----------------|----------------|--------------|
  64. | boolean | string | true -> 1 |
  65. | number | string | '1' -> 1 |
  66. | string | string | 'a' -> a |
  67. | null | string (empty) | null -> |
  68. | undefined | string (empty) | undefined -> |
  69. # Changes
  70. See [changelog](CHANGELOG.md)
  71. # API overview
  72. ## Constructor `require('node-object-hash')([options])`
  73. Returns preconfigured object with API
  74. Parameters:
  75. * `options`:`object` - object with hasher config options
  76. * `options.coerce`:`boolean` - if true performs type coercion (default: `true`);
  77. e.g. `hash(true) == hash('1') == hash(1)`, `hash(false) == hash('0') == hash(0)`
  78. * `options.sort`:`boolean` - if true performs sorting on objects, arrays, etc. (default: `true`);
  79. * `options.alg`:`string` - sets default hash algorithm (default: `'sha256'`); can be overridden in `hash` method;
  80. * `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;
  81. ## API methods
  82. ### `hash(object[, options])`
  83. Returns hash string.
  84. * `object`:`*` object for calculating hash;
  85. * `options`:`object` object with options;
  86. * `options.alg`:`string` - hash algorithm (default: `'sha256'`);
  87. * `options.enc`:`string` - hash encoding (default: `'hex'`);
  88. ### `sort(object)`
  89. Returns sorted string generated from object (can be used for object comparison)
  90. * `object`:`*` - object for sorting;
  91. # Full API docs ([separate page](API.md))
  92. {{>main}}
  93. # Requirements
  94. ## version \>=1.0.0
  95. - `>=nodejs-0.10.0`
  96. ## version \>=0.1.0 && <1.0.0
  97. - `>=nodejs-6.0.0`
  98. - `>=nodejs-4.0.0` (requires to run node with `--harmony` flag)
  99. ## browsers
  100. - nodejs `crypto` module for browsers (e.g. [browserify-crypto](https://github.com/crypto-browserify/crypto-browserify)).
  101. # Example
  102. ```js
  103. var hasher = require('node-object-hash');
  104. var hashSortCoerce = hasher({sort:true, coerce:true});
  105. // or
  106. // var hashSortCoerce = hasher();
  107. // or
  108. // var hashSort = hasher({sort:true, coerce:false});
  109. // or
  110. // var hashCoerce = hasher({sort:false, coerce:true});
  111. var objects = {
  112. a: {
  113. a: [{c: 2, a: 1, b: {a: 3, c: 2, b: 0}}],
  114. b: [1, 'a', {}, null],
  115. },
  116. b: {
  117. b: ['a', 1, {}, undefined],
  118. a: [{c: '2', b: {b: false, c: 2, a: '3'}, a: true}]
  119. },
  120. c: ['4', true, 0, 2, 3]
  121. };
  122. hashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);
  123. // returns true
  124. hashSortCoerce.sort(object.c);
  125. // returns '[0,1,2,3,4]'
  126. ```
  127. For more examples you can see [tests file](https://github.com/SkeLLLa/node-object-hash/blob/master/test/hash2.js)
  128. or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)
  129. # Benchmarks
  130. Bench data - array of 100000 complex objects
  131. ## Usage
  132. * `npm run bench` to run custom benchmark
  133. * `npm run bench2` to run benchmark suite
  134. ## Results
  135. ### Custom benchmark ([code](bench/index.js))
  136. | Library | Time (ms) | Memory (Mb) |
  137. |---------------------------------------|------------|--------------------|
  138. | node-object-hash-0.2.1 | 5813.575 | 34 |
  139. | node-object-hash-1.0.X | 2805.581 | 27 |
  140. | node-object-hash-1.1.X (node v7) | 2555.583 | 27 |
  141. | node-object-hash-1.2.X (node v7) | 2390.752 | 28 |
  142. | object-hash-1.1.5 (node v7) | 28115.553 | 39 |
  143. | object-hash-1.1.4 | 534528.254 | 41 |
  144. | object-hash-1.1.3 | ERROR | Out of heap memory |
  145. | hash-object-0.1.7 | 9219.826 | 42 |
  146. ### Benchmark suite module ([code](bench/bench.js))
  147. | Library (node v7) | Perf (ops/s) |
  148. |------------------------|--------------|
  149. | node-object-hash-0.2.1 | 540 ±1.34% |
  150. | node-object-hash-1.1.X | 844 ±2.51% |
  151. | node-object-hash-1.2.X | 1021 ±1.81% |
  152. | object-hash-1.1.5 | 106 ±0.88% |
  153. | hash-object-0.1.7 | 305 ±1.66% |
  154. | Library (node v10) | Perf (ops/s) |
  155. |------------------------|--------------|
  156. | node-object-hash-0.X.X | 758 ±1.40% |
  157. | node-object-hash-1.4.X | 1266 ±1.44% |
  158. | object-hash-1.3.0 | 132 ±4.08% |
  159. | hash-object-0.1.7 | 378 ±1.36% |
  160. ## Links
  161. * [object-hash](https://www.npmjs.com/package/object-hash) - Slow, useful for browsers because it not uses node's crypto library
  162. * [hash-object](https://www.npmjs.com/package/hash-object) - no ES6 types support
  163. # License
  164. ISC