{"id":13526510,"url":"https://github.com/SkeLLLa/node-object-hash","last_synced_at":"2025-04-01T07:32:45.428Z","repository":{"id":9595133,"uuid":"62706590","full_name":"SkeLLLa/node-object-hash","owner":"SkeLLLa","description":"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.","archived":false,"fork":false,"pushed_at":"2023-05-24T17:16:28.000Z","size":759,"stargazers_count":84,"open_issues_count":1,"forks_count":20,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-02T06:21:27.313Z","etag":null,"topics":["hash","hashing-library","javascript","js","node","node-crypto","nodejs","sorter","sorting"],"latest_commit_sha":null,"homepage":"https://savelife.in.ua/en/donate-en/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SkeLLLa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-06T08:58:05.000Z","updated_at":"2024-05-27T08:29:09.000Z","dependencies_parsed_at":"2024-06-18T12:41:49.617Z","dependency_job_id":"90d14b48-fdec-47d9-8988-a198f4189a7d","html_url":"https://github.com/SkeLLLa/node-object-hash","commit_stats":{"total_commits":191,"total_committers":15,"mean_commits":"12.733333333333333","dds":0.8115183246073299,"last_synced_commit":"56d25e0d35885fe051e770342742b42387496ee0"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SkeLLLa%2Fnode-object-hash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SkeLLLa%2Fnode-object-hash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SkeLLLa%2Fnode-object-hash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SkeLLLa%2Fnode-object-hash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SkeLLLa","download_url":"https://codeload.github.com/SkeLLLa/node-object-hash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222709772,"owners_count":17026764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hash","hashing-library","javascript","js","node","node-crypto","nodejs","sorter","sorting"],"created_at":"2024-08-01T06:01:30.806Z","updated_at":"2024-11-02T11:31:16.486Z","avatar_url":"https://github.com/SkeLLLa.png","language":"TypeScript","readme":"# node-object-hash\n\n\u003cdiv style=\"margin: 24px 0 16px;\"\u003e\n\u003cimg src=\"https://gitlab.com/m03geek/node-object-hash/raw/master/logo.svg\" align=\"left\" width=\"256\" height=\"auto\" alt=\"logo\" /\u003e\n\nTiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes.\nIt also provides a method that returns sorted object strings that can be used for object comparison without hashes.\nOne of the fastest among other analogues (see [benchmarks](#benchmarks)).\n\nHashes 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.\n\n[![Node](https://img.shields.io/node/v/node-object-hash.svg)](https://nodejs.org/download/release/latest)\n[![NPM Version](https://img.shields.io/npm/v/node-object-hash.svg)](https://www.npmjs.com/package/node-object-hash)\n[![Downloads Count](https://img.shields.io/npm/dm/node-object-hash.svg)](https://www.npmjs.com/package/node-object-hash)\n[![Vunerabilities Count](https://snyk.io/test/npm/node-object-hash/badge.svg)](https://www.npmjs.com/package/node-object-hash)\n[![Npms.io Score](https://badges.npms.io/node-object-hash.svg)](https://npms.io/search?q=node-object-hash)\n[![Build Status](https://github.com/SkeLLLa/node-object-hash/workflows/build/badge.svg)](https://github.com/SkeLLLa/node-object-hash/commits/master)\n[![License](https://img.shields.io/npm/l/node-object-hash.svg)](https://gitlab.com/m03geek/node-object-hash/blob/master/LICENSE)\n[![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)\n\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n## ToC\n\n- [node-object-hash](#node-object-hash)\n  - [ToC](#toc)\n  - [What's new in v3.0.0](#whats-new-in-v300)\n  - [What's new in v2.0.0](#whats-new-in-v200)\n    - [Breaking changes](#breaking-changes)\n    - [New features](#new-features)\n  - [Installation](#installation)\n  - [Features](#features)\n    - [Type map](#type-map)\n    - [Coercion map](#coercion-map)\n  - [Changes](#changes)\n  - [Docs](#docs)\n    - [API overview](#api-overview)\n      - [Constructor](#constructor)\n    - [API methods](#api-methods)\n      - [`hash(object[, options])`](#hashobject-options)\n      - [`sort(object)`](#sortobject)\n    - [Hashing custom objects](#hashing-custom-objects)\n  - [Requirements](#requirements)\n    - [version \\\u003e=1.0.0](#version-100)\n    - [version \\\u003e=0.1.0 \\\u0026\\\u0026 \\\u003c1.0.0](#version-010--100)\n  - [Examples](#examples)\n  - [Benchmarks](#benchmarks)\n    - [Usage](#usage)\n    - [Results](#results)\n      - [Custom benchmark (code)](#custom-benchmark-code)\n      - [Benchmark suite module (code)](#benchmark-suite-module-code)\n    - [Links](#links)\n  - [License](#license)\n\n## What's new in v3.0.0\n\n**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.\n\n- Refactor and migration to typescript 5.\n- Drop old node support.\n- Removed typescript namespaces.\n- Updated exported functions and object structure.\n- Removed faker and old benchmarks.\n- New CI and release automation.\n\n## What's new in v2.0.0\n\n### Breaking changes\n\n- Library rewritten in typescript that could cause some side-effects, but it should not.\n- 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`.\n- 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.\n  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:\n\n```\nconst hasher = require('node-object-hash')({coerce: {set: true, symbol: true}})\n```\n\n- 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').\n- Removed old `v0` version from code.\n- Changed license to MIT.\n\n### New features\n\n- New granular options. Now you can specify what types need to be sorted or coerced.\n- Add new `trim` option. It can be used to remove unncecessary spaces in `string`s or `function` bodies.\n- Library rewritten to typescript, so it may have better ts compatibility.\n\n## Installation\n\n`npm i node-object-hash -S`\n\n## Features\n\n- Supports object property sorting for constant hashes for objects with same properties, but different order.\n- Supports ES6 Maps and Sets.\n- Supports type coercion (see table below).\n- Supports all hashes and encodings of crypto library.\n- Supports large objects and arrays.\n- Has granular options that allows to control what should be sorted or coerced.\n- Very fast comparing to other libs (see [Benchmarks](#benchmarks) section).\n\n### Type map\n\nThis map displays what types will have identical string representation (e.g. new Set([1, 2, 3]) and [1, 2, 3] will have\nequal string representations and hashes.\n\n| Initial type              | Mapped type  |\n| ------------------------- | ------------ |\n| Array ([])                | array        |\n| ArrayObject (new Array()) |              |\n| Int8Array                 |              |\n| Uint8Array                |              |\n| Uint8ClampedArray         |              |\n| Int16Array                |              |\n| Uint16Array               |              |\n| Int32Array                |              |\n| Uint32Array               |              |\n| Float32Array              |              |\n| Float64Array              |              |\n| Buffer                    |              |\n| Set                       |              |\n|                           |              |\n| Map                       | array[array] |\n|                           |              |\n| string ('')               | string       |\n| String (new String())     |              |\n|                           |              |\n| boolean (true)            | boolean      |\n| Boolean (new Boolean())   |              |\n|                           |              |\n| number (true)             | number       |\n| Number (new Number())     |              |\n|                           |              |\n| Date                      | date         |\n|                           |              |\n| Symbol                    | symbol       |\n|                           |              |\n| undefined                 | undefined    |\n|                           |              |\n| null                      | null         |\n|                           |              |\n| function                  | function     |\n|                           |              |\n| Object ({})               | object       |\n| Object (new Object())     |              |\n|                           |              |\n| other                     | unknown      |\n\n### Coercion map\n\n| Initial \"type\" | Coerced type   | Example      |\n| -------------- | -------------- | ------------ |\n| boolean        | string         | true -\u003e 1    |\n| number         | string         | '1' -\u003e 1     |\n| string         | string         | 'a' -\u003e a     |\n| null           | string (empty) | null -\u003e      |\n| undefined      | string (empty) | undefined -\u003e |\n\n## Changes\n\nSee [changelog](docs/CHANGELOG.md)\nFor v2 changes see [changelog-v2](docs/CHANGELOG-v2.md)\n\n## Docs\n\nFull API docs could be found in [docs](./docs/api/README.md).\n\n### API overview\n\n#### Constructor\n\n```js\nrequire('node-object-hash').hasher([options]);\n```\n\nReturns preconfigured object with API\n\nParameters:\n\n- `options`:`object` - object with hasher config options\n- `options.coerce`:`boolean|object` - if true performs type coercion (default: `true`);\n  e.g. `hash(true) == hash('1') == hash(1)`, `hash(false) == hash('0') == hash(0)`\n- `options.sort`:`boolean|object` - if true performs sorting on objects, arrays, etc. (default: `true`); in order to\n  perform sorting on `TypedArray` (`Buffer`, `Int8Array`, etc.), specify it explicitly: `typedArray: true`\n- `options.trim`:`boolean|object` - if true performs trim of spaces and replaces space-like characters with single space (default: `false`);\n- `options.alg`:`string` - sets default hash algorithm (default: `'sha256'`); can be overridden in `hash` method;\n- `options.enc`:`string` - sets default hash encoding (default: `'hex'`); can be overridden in `hash` method;\n\n### API methods\n\n#### `hash(object[, options])`\n\nReturns hash string.\n\n- `object`:`*` object for calculating hash;\n- `options`:`object` object with options;\n- `options.alg`:`string` - hash algorithm (default: `'sha256'`);\n- `options.enc`:`string` - hash encoding (default: `'hex'`);\n\n#### `sort(object)`\n\nReturns sorted string generated from object (can be used for object comparison)\n\n- `object`:`*` - object for sorting;\n\n### Hashing custom objects\n\nIn 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.\n\nFor typescript users you may add to your classes `implements Hashable`.\n\n## Requirements\n\n### version \\\u003e=1.0.0\n\n- `\u003e=nodejs-0.10.0`\n\n### version \\\u003e=0.1.0 \u0026\u0026 \u003c1.0.0\n\n- `\u003e=nodejs-6.0.0`\n- `\u003e=nodejs-4.0.0` (requires to run node with `--harmony` flag)\n\n## Examples\n\n```js\nvar { hasher } = require('node-object-hash');\n\nvar hashSortCoerce = hasher({ sort: true, coerce: true });\n// or\n// var hashSortCoerce = hasher();\n// or\n// var hashSort = hasher({sort:true, coerce:false});\n// or\n// var hashCoerce = hasher({sort:false, coerce:true});\n\nvar objects = {\n  a: {\n    a: [{ c: 2, a: 1, b: { a: 3, c: 2, b: 0 } }],\n    b: [1, 'a', {}, null],\n  },\n  b: {\n    b: ['a', 1, {}, undefined],\n    a: [{ c: '2', b: { b: false, c: 2, a: '3' }, a: true }],\n  },\n  c: ['4', true, 0, 2, 3],\n};\n\nhashSortCoerce.hash(objects.a) === hashSortCoerce.hash(objects.b);\n// returns true\n\nhashSortCoerce.sort(object.c);\n// returns '[0,1,2,3,4]'\n```\n\nFor more examples you can see [tests](./test) or try it out online at [runkit](https://runkit.com/skellla/node-object-hash-example)\n\n## Benchmarks\n\nBench data - array of 100000 complex objects\n\n### Usage\n\n- `npm run bench` to run custom benchmark\n- `npm run benchmark` to run benchmark suite\n- `npm run benchmark:hash` to run hash benchmark suite\n\n### Results\n\n| Hashing algorithm  | Result hash bytes length | Performance (ops/sec) |\n| ------------------ | ------------------------ | --------------------- |\n| `sha256` (default) | 64                       | 1,599 +- 5.77%        |\n| `sha1`             | 40                       | 1,983 +- 1.50%        |\n| `sha224`           | 56                       | 1,701 +- 2.81%        |\n| `sha384`           | 96                       | 1,800 +- 0.81%        |\n| `sha512`           | 128                      | 1,847 +- 1.75%        |\n| `md4`              | 32                       | 1,971 +- 0.98%        |\n| `md5`              | 32                       | 1,691 +- 3.18%        |\n| `whirlpool`        | 128                      | 1,487 +- 2.33%        |\n|                    |                          |                       |\n\n#### Custom benchmark ([code](bench/index.js))\n\n| Library                           | Time (ms)  | Memory (Mb)        |\n| --------------------------------- | ---------- | ------------------ |\n| node-object-hash-0.2.1            | 5813.575   | 34                 |\n| node-object-hash-1.0.X            | 2805.581   | 27                 |\n| node-object-hash-1.1.X (node v7)  | 2555.583   | 27                 |\n| node-object-hash-1.2.X (node v7)  | 2390.752   | 28                 |\n| node-object-hash-2.X.X (node v12) | 1990.622   | 24                 |\n| object-hash-1.1.5 (node v7)       | 28115.553  | 39                 |\n| object-hash-1.1.4                 | 534528.254 | 41                 |\n| object-hash-1.1.3                 | ERROR      | Out of heap memory |\n| hash-object-0.1.7                 | 9219.826   | 42                 |\n\n#### Benchmark suite module ([code](bench/bench.js))\n\n| Library (node v12)     | Perf (ops/s) |\n| ---------------------- | ------------ |\n| node-object-hash-2.0.0 | 2087 ±0.59%  |\n| object-hash-1.3.1      | 239 ±0.39%   |\n| hash-object-0.1.7      | 711 ±0.18%   |\n\n### Links\n\n- [object-hash](https://www.npmjs.com/package/object-hash) - Slow, useful for browsers because it not uses node's crypto library\n- [hash-object](https://www.npmjs.com/package/hash-object) - no ES6 types support\n\n## License\n\nMIT\n","funding_links":[],"categories":["Repository"],"sub_categories":["Crypto"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSkeLLLa%2Fnode-object-hash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSkeLLLa%2Fnode-object-hash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSkeLLLa%2Fnode-object-hash/lists"}