From 339f38c1b03047e62679c7e0f105162dc85bd742 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Tue, 19 Sep 2017 08:35:55 +0200 Subject: [PATCH] Moved string hashing function away from main files --- lib/stringUtils.js | 14 ++++++++++++ lib/stringUtils.spec.js | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/stringUtils.js create mode 100644 lib/stringUtils.spec.js diff --git a/lib/stringUtils.js b/lib/stringUtils.js new file mode 100644 index 00000000..6d73348e --- /dev/null +++ b/lib/stringUtils.js @@ -0,0 +1,14 @@ +function hashCode(string){ + if(typeof string !== "string") throw "ERROR: Not a string"; + var hash = 0; + if (string.length == 0) return hash; + for (let i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + hash = ((hash << 5) - hash) + char; + hash = hash & hash; // Convert to 32bit integer + } + return hash; +} +module.exports = { + hashCode: hashCode, +} \ No newline at end of file diff --git a/lib/stringUtils.spec.js b/lib/stringUtils.spec.js new file mode 100644 index 00000000..f16f19ca --- /dev/null +++ b/lib/stringUtils.spec.js @@ -0,0 +1,48 @@ +const assert = require("assert"); +const stringUtils = require("./stringUtils"); + +describe("stringUtils.js", function(){ + describe("hashCode", function(){ + it("Produces a 32bit signed int hash from a string", function(){ + let x = stringUtils.hashCode("whatever"); + let y = stringUtils.hashCode(" a much longer string to prove this works for long strings as well and also special characters &!¤(#)¤"); + + assert(typeof x == "number", "hashCode should be returning a 32 bit signed int"); + assert(x.toString() == "1934383586"); + assert(y.toString() == "1648886132"); + }); + let permutations = 1000; + it("Rarely produces same hash for different strings ("+permutations+" hashes with collision check)", function(){ + let keyHashPairs = []; + for(let i = 0; i < permutations; i++){ + let string = Math.random().toString(); + keyHashPairs.push({ + key:string, + hash:stringUtils.hashCode(string), + }); + } + + for(let i = 0; i < permutations; i++){ + for(let o = 0; o < permutations; o++){ + assert(i == o || keyHashPairs[o].key != keyHashPairs[i].key, "Woha, Math.random() generated 2 equal numbers???"); + assert(i == o || keyHashPairs[o].hash != keyHashPairs[i].hash, "Hash collision, as long at it doesn't happen again its fine."); + } + } + }); + it("Returns 0 for 0 length strings", function(){ + let x = stringUtils.hashCode(""); + assert.deepEqual(x, 0); + }); + it("Throws when supplied with anything other than a string", function(){ + assert.throws(function(){ + stringUtils.hashCode([]); + }, "ERROR: Not a string") + assert.throws(function(){ + stringUtils.hashCode({}); + }, "ERROR: Not a string") + assert.throws(function(){ + stringUtils.hashCode(0); + }, "ERROR: Not a string") + }); + }); +}); \ No newline at end of file