Skip to content

Commit bf827b2

Browse files
committed
Java hashcode functions for Nodejs
1 parent f1a3994 commit bf827b2

4 files changed

Lines changed: 164 additions & 0 deletions

File tree

index.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
let long = require('long');
2+
3+
exports.jHashCode = function(stringToBeHashed) {
4+
let hash = 0, i, chr;
5+
if (stringToBeHashed.length === 0) return hash;
6+
for (i = 0; i < stringToBeHashed.length; i++) {
7+
chr = stringToBeHashed.charCodeAt(i);
8+
hash = ((hash << 5) - hash) + chr;
9+
hash |= 0;
10+
}
11+
return hash
12+
}
13+
14+
exports.jUUIDHashCode = function(uuidToBeHashed) {
15+
16+
if (!uuidToBeHashed.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i)) {
17+
throw TypeError("Invalid UUID string");
18+
}
19+
20+
let uuidSplits = uuidToBeHashed.split("-");
21+
let msb = long.fromString(uuidSplits[0], false, 16).and(0xffffffff);
22+
msb = msb.shiftLeft(16);
23+
msb = msb.or(long.fromString(uuidSplits[1], false, 16).and(0xffff));
24+
msb = msb.shiftLeft(16);
25+
msb = msb.or(long.fromString(uuidSplits[2], false, 16).and(0xffff));
26+
27+
let lsb = long.fromString(uuidSplits[3], false, 16).and(0xffff);
28+
lsb = lsb.shiftLeft(48);
29+
lsb = lsb.or(long.fromString(uuidSplits[4], false, 16).and(0xffffffffffff));
30+
31+
let hilo = msb.xor(lsb);
32+
return hilo.shiftRight(32).toInt() ^ hilo.toInt();
33+
}

package-lock.json

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "jhash",
3+
"version": "1.0.0",
4+
"description": "Java hashcode functions for Nodejs",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "node test.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/bytecodehq/jhash.git"
12+
},
13+
"keywords": [
14+
"java",
15+
"string-hashcode",
16+
"hashcode",
17+
"uuid",
18+
"uuid-hashcode"
19+
],
20+
"author": "Akhil Bojedla",
21+
"license": "MIT",
22+
"bugs": {
23+
"url": "https://github.com/bytecodehq/jhash/issues"
24+
},
25+
"homepage": "https://github.com/bytecodehq/jhash#readme",
26+
"dependencies": {
27+
"long": "^5.2.0"
28+
}
29+
}

test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const { jHashCode, jUUIDHashCode } = require(".");
2+
3+
test_jHashCode = function () {
4+
const testCases = [
5+
{
6+
"input": "java",
7+
"hashCode": 3254818
8+
},
9+
{
10+
"input": "javascript",
11+
"hashCode": 188995949
12+
},
13+
{
14+
"input": "ecmascript",
15+
"hashCode": -948769283
16+
}
17+
]
18+
19+
testCases.forEach((testCase) => {
20+
if (jHashCode(testCase["input"]) !== testCase["hashCode"]) {
21+
throw EvalError("jHashCode generated hascode not consistent with Java hashcode")
22+
}
23+
});
24+
}
25+
26+
test_jHashCode_returns_0_on_empty_string = function () {
27+
if (jHashCode("") !== 0) {
28+
throw EvalError("jHashCode generated hascode not consistent with Java hashcode");
29+
}
30+
}
31+
32+
test_jUUIDHashCode = function() {
33+
const testCases = [
34+
{
35+
"input": "90903f27-e36e-4e6f-996a-124c58365b43",
36+
"hashCode": -1297991609
37+
},
38+
{
39+
"input": "20adfcb5-d0e7-4157-a94e-fcb749f25168",
40+
"hashCode": 284561469
41+
},
42+
{
43+
"input": "737de8e7-9ae9-4208-95c3-9514309c5032",
44+
"hashCode": 1288400841
45+
}
46+
];
47+
48+
testCases.forEach((testCase) => {
49+
if (jUUIDHashCode(testCase["input"]) !== testCase["hashCode"]) {
50+
throw EvalError("jUUIDHashCode generated hascode not consistent with Java UUID hashcode")
51+
}
52+
});
53+
}
54+
55+
test_jUUIDHashCode_throws_TypError_on_non_UUID = function() {
56+
let exceptionThrown = false;
57+
try {
58+
jUUIDHashCode("foo")
59+
} catch (error) {
60+
if (error instanceof TypeError) {
61+
exceptionThrown = true;
62+
}
63+
}
64+
65+
if (!exceptionThrown) {
66+
throw EvalError("jUUIDHashCode did not throw TypeError on non UUID string")
67+
}
68+
}
69+
70+
test_jHashCode();
71+
test_jHashCode_returns_0_on_empty_string();
72+
test_jUUIDHashCode();
73+
test_jUUIDHashCode_throws_TypError_on_non_UUID();

0 commit comments

Comments
 (0)