pax_global_header00006660000000000000000000000064135055027770014525gustar00rootroot0000000000000052 comment=6b528bacaa7e1c9031cd649c718f4106a17e827d hash-sum-2.0.0/000077500000000000000000000000001350550277700132515ustar00rootroot00000000000000hash-sum-2.0.0/.editorconfig000066400000000000000000000003171350550277700157270ustar00rootroot00000000000000# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false hash-sum-2.0.0/.gitignore000066400000000000000000000000331350550277700152350ustar00rootroot00000000000000node_modules npm-debug.log hash-sum-2.0.0/.jshintignore000066400000000000000000000000151350550277700157510ustar00rootroot00000000000000node_modules hash-sum-2.0.0/.jshintrc000066400000000000000000000005311350550277700150750ustar00rootroot00000000000000{ "curly": true, "eqeqeq": true, "newcap": true, "noarg": true, "noempty": true, "nonew": true, "sub": true, "validthis": true, "undef": true, "trailing": true, "boss": true, "eqnull": true, "strict": true, "immed": true, "expr": true, "latedef": "nofunc", "quotmark": "single", "indent": 2, "node": true } hash-sum-2.0.0/changelog.markdown000066400000000000000000000004231350550277700167430ustar00rootroot00000000000000# 2.0.0 - Now takes into account result of calling `valueOf` functions when they exist # 1.0.2 Quick Sort - Sorts object keys so that property order doesn't affect outcome # 1.0.1 Perfect Circle - Guard against circular references # 1.0.0 IPO - Initial Public Release hash-sum-2.0.0/hash-sum.js000066400000000000000000000030061350550277700153330ustar00rootroot00000000000000'use strict'; function pad (hash, len) { while (hash.length < len) { hash = '0' + hash; } return hash; } function fold (hash, text) { var i; var chr; var len; if (text.length === 0) { return hash; } for (i = 0, len = text.length; i < len; i++) { chr = text.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } return hash < 0 ? hash * -2 : hash; } function foldObject (hash, o, seen) { return Object.keys(o).sort().reduce(foldKey, hash); function foldKey (hash, key) { return foldValue(hash, o[key], key, seen); } } function foldValue (input, value, key, seen) { var hash = fold(fold(fold(input, key), toString(value)), typeof value); if (value === null) { return fold(hash, 'null'); } if (value === undefined) { return fold(hash, 'undefined'); } if (typeof value === 'object' || typeof value === 'function') { if (seen.indexOf(value) !== -1) { return fold(hash, '[Circular]' + key); } seen.push(value); var objHash = foldObject(hash, value, seen) if (!('valueOf' in value) || typeof value.valueOf !== 'function') { return objHash; } try { return fold(objHash, String(value.valueOf())) } catch (err) { return fold(objHash, '[valueOf exception]' + (err.stack || err.message)) } } return fold(hash, value.toString()); } function toString (o) { return Object.prototype.toString.call(o); } function sum (o) { return pad(foldValue(0, o, '', []).toString(16), 8); } module.exports = sum; hash-sum-2.0.0/license000066400000000000000000000020721350550277700146170ustar00rootroot00000000000000The MIT License (MIT) Copyright © 2014 Nicolas Bevacqua Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. hash-sum-2.0.0/package-lock.json000066400000000000000000000270441350550277700164740ustar00rootroot00000000000000{ "name": "hash-sum", "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "ansi-styles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chalk": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", "dev": true, "requires": { "ansi-styles": "~1.0.0", "has-color": "~0.1.0", "strip-ansi": "~0.1.0" } }, "cli": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz", "integrity": "sha1-ePlIXNFhtWbppsctcXDEJw6B22E=", "dev": true, "requires": { "glob": ">= 3.1.4" } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "console-browserify": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-0.1.6.tgz", "integrity": "sha1-0SijwLuINQ61YmxufHGm8P1ImDw=", "dev": true }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, "deep-equal": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=", "dev": true }, "defined": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=", "dev": true }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, "domhandler": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", "dev": true, "requires": { "domelementtype": "1" } }, "domutils": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", "dev": true, "requires": { "domelementtype": "1" } }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "dependencies": { "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } } } }, "has-color": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", "dev": true }, "htmlparser2": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", "dev": true, "requires": { "domelementtype": "1", "domhandler": "2.1", "domutils": "1.1", "readable-stream": "1.0" } }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "jshint": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.5.0.tgz", "integrity": "sha1-gv0aI1/851+tG0Cyo4vvR76sjFQ=", "dev": true, "requires": { "cli": "0.4.x", "console-browserify": "0.1.x", "exit": "0.1.x", "htmlparser2": "3.3.x", "minimatch": "0.x.x", "shelljs": "0.1.x", "strip-json-comments": "0.1.x", "underscore": "1.4.x" } }, "jshint-stylish": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-0.2.0.tgz", "integrity": "sha1-newAJQrISXlgvk7tb1Bn+x1twH0=", "dev": true, "requires": { "chalk": "~0.4.0", "text-table": "~0.2.0" } }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lru-cache": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", "dev": true }, "minimatch": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.4.0.tgz", "integrity": "sha1-vSx9Bg0sjI/Xzefx8u0tWycP2xs=", "dev": true, "requires": { "lru-cache": "2", "sigmund": "~1.0.0" } }, "object-inspect": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-0.4.0.tgz", "integrity": "sha1-9RV8EWwUVbJDsG7pdwM5LFrYn+w=", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "resumer": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", "dev": true, "requires": { "through": "~2.3.4" } }, "shelljs": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.1.4.tgz", "integrity": "sha1-37vnjVbDwBaNL7eeEOzR28sH7A4=", "dev": true }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "strip-ansi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true }, "strip-json-comments": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", "integrity": "sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ=", "dev": true }, "tape": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/tape/-/tape-3.0.3.tgz", "integrity": "sha1-3E0oqPPBHlRrAZiAzgPnjVCTtVQ=", "dev": true, "requires": { "deep-equal": "~0.2.0", "defined": "~0.0.0", "glob": "~3.2.9", "inherits": "~2.0.1", "object-inspect": "~0.4.0", "resumer": "~0.0.0", "through": "~2.3.4" }, "dependencies": { "glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", "dev": true, "requires": { "inherits": "2", "minimatch": "0.3" } }, "minimatch": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", "dev": true, "requires": { "lru-cache": "2", "sigmund": "~1.0.0" } } } }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "underscore": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz", "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=", "dev": true }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true } } } hash-sum-2.0.0/package.json000066400000000000000000000012101350550277700155310ustar00rootroot00000000000000{ "name": "hash-sum", "description": "Blazing fast unique hash generator", "version": "2.0.0", "homepage": "https://github.com/bevacqua/hash-sum", "authors": [ "Nicolas Bevacqua " ], "license": "MIT", "repository": { "type": "git", "url": "git://github.com/bevacqua/hash-sum.git" }, "bugs": { "url": "https://github.com/bevacqua/hash-sum/issues" }, "main": "hash-sum.js", "scripts": { "test": "jshint . && tape test.js" }, "dependencies": {}, "devDependencies": { "jshint": "2.5.0", "jshint-stylish": "0.2.0", "lodash": "4.17.11", "tape": "3.0.3" } } hash-sum-2.0.0/readme.md000066400000000000000000000034521350550277700150340ustar00rootroot00000000000000# hash-sum > blazing fast unique hash generator # install ```shell npm i hash-sum -S ``` # features - no dependencies - minimal footprint - works in all of node.js, io.js, and the browser - hashes functions based on their source code - produces different hashes for different object types - support for circular references in objects - ignores property assignment order # `sum(value)` yields a four-byte hexadecimal hash based off of `value`. ``` # creates unique hashes 00a34759 from: [ 0, 1, 2, 3 ] a8996f0c from: { '0': 0, '1': 1, '2': 2, '3': 3 } 5b4c2116 from: { '0': 0, '1': 1, '2': 2, '3': 3, length: 4 } 2c937c45 from: { url: 12 } 31d55010 from: { headers: 12 } 2d2e11bc from: { headers: 122 } ec99d958 from: { headers: '122' } 18c00eee from: { headers: { accept: 'text/plain' } } 6cb332c8 from: { payload: [ 0, 1, 2, 3 ], headers: [ { a: 'b' } ] } 12ff55db from: { a: [Function: a] } 46f806d2 from: { b: [Function: b] } 0660d9c4 from: { b: [Function: b] } 6c95fc65 from: function () {} 2941766e from: function (a) {} 294f8def from: function (b) {} 2d9c0cb8 from: function (a) { return a;} ed5c63fc from: function (a) {return a;} bba68bf6 from: '' 2d27667d from: 'null' 774b96ed from: 'false' 2d2a1684 from: 'true' 8daa1a0c from: '0' 8daa1a0a from: '1' e38f07cc from: 'void 0' 6037ea1a from: 'undefined' 9b7df12e from: null 3c206f76 from: false 01e34ba8 from: true 8a8f9624 from: Infinity 0315bf8f from: -Infinity 64a48b16 from: NaN 1a96284a from: 0 1a96284b from: 1 29172c1a from: undefined 59322f29 from: {} 095b3a22 from: { a: {}, b: {} } 63be56dd from: { valueOf: [Function: valueOf] } 63be4f5c from: { valueOf: [Function: valueOf] } 5d844489 from: [] ba0bfa14 from: 2019-06-28T21:24:31.215Z 49324d16 from: 2019-06-28T03:00:00.000Z 434c9188 from: 1988-06-09T03:00:00.000Z ce1b5e44 from: global ``` # license MIT hash-sum-2.0.0/test.js000066400000000000000000000042061350550277700145700ustar00rootroot00000000000000'use strict'; var _ = require('lodash'); var test = require('tape'); var sum = require('./'); test('creates unique hashes', function (t) { var cases = []; test_case([0,1,2,3]); test_case({0:0,1:1,2:2,3:3}); test_case({0:0,1:1,2:2,3:3,length:4}); test_case({url:12}); test_case({headers:12}); test_case({headers:122}); test_case({headers:'122'}); test_case({headers:{accept:'text/plain'}}); test_case({payload:[0,1,2,3],headers:[{a:'b'}]}); test_case({a:function () {}}); test_case({b:function () {}}); test_case({b:function (a) {}}); test_case(function () {}); test_case(function (a) {}); test_case(function (b) {}); test_case(function (a) { return a;}); test_case(function (a) {return a;}); test_case('', '\'\''); test_case('null', '\'null\''); test_case('false', '\'false\''); test_case('true', '\'true\''); test_case('0', '\'0\''); test_case('1', '\'1\''); test_case('void 0', '\'void 0\''); test_case('undefined', '\'undefined\''); test_case(null); test_case(false); test_case(true); test_case(Infinity); test_case(-Infinity); test_case(NaN); test_case(0); test_case(1); test_case(void 0); test_case({}); test_case({a:{},b:{}}); test_case({valueOf(){return 1}}); test_case({valueOf(){return 2}}); test_case([]); test_case(new Date()); test_case(new Date(2019, 5, 28)); test_case(new Date(1988, 5, 9)); test_case(global, 'global'); const uniqCases = _.uniqBy(cases, 'hash') _.uniqBy(cases, 'hash').forEach(function (expected) { var matches = _.filter(cases, { hash: expected.hash }) t.equal(matches.length, 1, expected.hash + ': ' + _.map(matches, 'value').join(' ')) }) t.end(); function test_case(value, name) { var hash = sum(value); cases.push({ value, hash }); console.log('%s from:', hash, name || value); } }); test('hashes clash if same properties', function (t) { equals(function () {}, function () {}); equals(function (a) {}, function (a) {}); equals({a:'1'},{a:'1'}); equals({a:'1',b:1},{b:1,a:'1'}); equals({valueOf(){return 1}},{valueOf(){return 1}}); t.end(); function equals (a, b) { t.equal(sum(a), sum(b)); } });