Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/SkeLLLa/node-object-hash
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.
https://github.com/SkeLLLa/node-object-hash
hash hashing-library javascript js node node-crypto nodejs sorter sorting
Last synced: 3 months ago
JSON representation
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.
- Host: GitHub
- URL: https://github.com/SkeLLLa/node-object-hash
- Owner: SkeLLLa
- License: mit
- Created: 2016-07-06T08:58:05.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2023-05-24T17:16:28.000Z (over 1 year ago)
- Last Synced: 2024-08-02T06:21:27.313Z (7 months ago)
- Topics: hash, hashing-library, javascript, js, node, node-crypto, nodejs, sorter, sorting
- Language: TypeScript
- Homepage: https://savelife.in.ua/en/donate-en/
- Size: 741 KB
- Stars: 84
- Watchers: 4
- Forks: 20
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
- awesome-nodejs - node-object-hash - 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. ![](https://img.shields.io/github/stars/SkeLLLa/node-object-hash.svg?style=social&label=Star) (Repository / Crypto)
README
# node-object-hash
![]()
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](#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](https://github.com/crypto-browserify/crypto-browserify) or some kind of crypto functions polyfills.
[![Node](https://img.shields.io/node/v/node-object-hash.svg)](https://nodejs.org/download/release/latest)
[![NPM Version](https://img.shields.io/npm/v/node-object-hash.svg)](https://www.npmjs.com/package/node-object-hash)
[![Downloads Count](https://img.shields.io/npm/dm/node-object-hash.svg)](https://www.npmjs.com/package/node-object-hash)
[![Vunerabilities Count](https://snyk.io/test/npm/node-object-hash/badge.svg)](https://www.npmjs.com/package/node-object-hash)
[![Npms.io Score](https://badges.npms.io/node-object-hash.svg)](https://npms.io/search?q=node-object-hash)
[![Build Status](https://github.com/SkeLLLa/node-object-hash/workflows/build/badge.svg)](https://github.com/SkeLLLa/node-object-hash/commits/master)
[![License](https://img.shields.io/npm/l/node-object-hash.svg)](https://gitlab.com/m03geek/node-object-hash/blob/master/LICENSE)
[![Codecov Coverage](https://codecov.io/gh/SkeLLLa/node-object-hash/branch/master/graph/badge.svg?token=wLjMou8TT7)](https://codecov.io/gh/SkeLLLa/node-object-hash)
## ToC
- [node-object-hash](#node-object-hash)
- [ToC](#toc)
- [What's new in v3.0.0](#whats-new-in-v300)
- [What's new in v2.0.0](#whats-new-in-v200)
- [Breaking changes](#breaking-changes)
- [New features](#new-features)
- [Installation](#installation)
- [Features](#features)
- [Type map](#type-map)
- [Coercion map](#coercion-map)
- [Changes](#changes)
- [Docs](#docs)
- [API overview](#api-overview)
- [Constructor](#constructor)
- [API methods](#api-methods)
- [`hash(object[, options])`](#hashobject-options)
- [`sort(object)`](#sortobject)
- [Hashing custom objects](#hashing-custom-objects)
- [Requirements](#requirements)
- [version \>=1.0.0](#version-100)
- [version \>=0.1.0 \&\& \<1.0.0](#version-010--100)
- [Examples](#examples)
- [Benchmarks](#benchmarks)
- [Usage](#usage)
- [Results](#results)
- [Custom benchmark (code)](#custom-benchmark-code)
- [Benchmark suite module (code)](#benchmark-suite-module-code)
- [Links](#links)
- [License](#license)## What's new in v3.0.0
**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.## What's new in v2.0.0
### Breaking changes
- Library rewritten in typescript that could cause some side-effects, but it should not.
- With `coerce=false` `Set`s will no longer generate the same hashes as `Array`s. In order to restore previous behavior set `coerce.set=true`.
- With `coerce=false` `Symbol`s will generate hash based on symbol `.toString` value. That's useful for `Symbol.for('smth')`. If `coerce.symbol=true` all `Symbols`s will have equal hashes.
TLDR; If you use library with `Set`s or `Symbol`s with `coerce=false` in order to keep hashes the same as in `v1.X.X` you should use following constructor:```
const hasher = require('node-object-hash')({coerce: {set: true, symbol: true}})
```- Object sorter sources moved to `dist` directory. If you required it directly via `require('node-object-hash/objectSorter')` you should change it to require('node-object-hash/dist/objectSorter').
- Removed old `v0` version from code.
- Changed license to MIT.### New features
- New granular options. Now you can specify what types need to be sorted or coerced.
- Add new `trim` option. It can be used to remove unncecessary spaces in `string`s or `function` bodies.
- Library rewritten to typescript, so it may have better ts compatibility.## Installation
`npm i node-object-hash -S`
## Features
- 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](#benchmarks) section).### Type map
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 |### Coercion map
| 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 -> |## Changes
See [changelog](docs/CHANGELOG.md)
For v2 changes see [changelog-v2](docs/CHANGELOG-v2.md)## Docs
Full API docs could be found in [docs](./docs/api/README.md).
### API overview
#### Constructor
```js
require('node-object-hash').hasher([options]);
```Returns preconfigured object with API
Parameters:
- `options`:`object` - object with hasher config options
- `options.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 on `TypedArray` (`Buffer`, `Int8Array`, etc.), specify it explicitly: `typedArray: true`
- `options.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 in `hash` method;
- `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;### API methods
#### `hash(object[, options])`
Returns hash string.
- `object`:`*` object for calculating hash;
- `options`:`object` object with options;
- `options.alg`:`string` - hash algorithm (default: `'sha256'`);
- `options.enc`:`string` - hash encoding (default: `'hex'`);#### `sort(object)`
Returns sorted string generated from object (can be used for object comparison)
- `object`:`*` - object for sorting;
### Hashing custom objects
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`.
## Requirements
### version \>=1.0.0
- `>=nodejs-0.10.0`
### version \>=0.1.0 && <1.0.0
- `>=nodejs-6.0.0`
- `>=nodejs-4.0.0` (requires to run node with `--harmony` flag)## Examples
```js
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 truehashSortCoerce.sort(object.c);
// returns '[0,1,2,3,4]'
```For more examples you can see [tests](./test) or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)
## Benchmarks
Bench data - array of 100000 complex objects
### Usage
- `npm run bench` to run custom benchmark
- `npm run benchmark` to run benchmark suite
- `npm run benchmark:hash` to run hash benchmark suite### Results
| 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](bench/index.js))
| 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](bench/bench.js))
| 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% |### Links
- [object-hash](https://www.npmjs.com/package/object-hash) - Slow, useful for browsers because it not uses node's crypto library
- [hash-object](https://www.npmjs.com/package/hash-object) - no ES6 types support## License
MIT