Skip to content

Commit a03c4fa

Browse files
committed
test: Use murmurhash3 instead of sha256
for tree hashing Signed-off-by: Marcel Klehr <[email protected]>
1 parent 0367b02 commit a03c4fa

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

src/lib/Crypto.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import { fromUint8Array, toUint8Array } from 'js-base64'
2+
import { murmurhash3_32_gc } from './murmurhash3'
23

34
export default class Crypto {
45
static iterations = 250000
56
static ivLength = 16
67

8+
static async murmurHash3(message: string): Promise<string> {
9+
const buf32 = new Uint32Array([murmurhash3_32_gc(message, 0)])
10+
const buf8 = new Uint8Array(buf32.buffer)
11+
buf8.reverse()
12+
return this.bufferToHexstr(buf8)
13+
}
14+
715
static async sha256(message: string): Promise<string> {
816
const msgBuffer = new TextEncoder().encode(message) // encode as UTF-8
917
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer) // hash the message

src/lib/Tree.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class Bookmark<L extends TItemLocation> {
8080

8181
async hash():Promise<string> {
8282
if (!this.hashValue) {
83-
this.hashValue = await Crypto.sha256(
83+
this.hashValue = await Crypto.murmurHash3(
8484
JSON.stringify({ title: this.title, url: this.url })
8585
)
8686
}
@@ -329,7 +329,7 @@ export class Folder<L extends TItemLocation> {
329329
})
330330
}
331331
if (!this.hashValue) this.hashValue = {}
332-
this.hashValue[String(preserveOrder)] = await Crypto.sha256(
332+
this.hashValue[String(preserveOrder)] = await Crypto.murmurHash3(
333333
JSON.stringify({
334334
title: this.title,
335335
children: await Parallel.map(

src/lib/murmurhash3.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)
3+
*
4+
* @author <a href="mailto:[email protected]">Gary Court</a>
5+
* @see http://github.com/garycourt/murmurhash-js
6+
* @author <a href="mailto:[email protected]">Austin Appleby</a>
7+
* @see http://sites.google.com/site/murmurhash/
8+
*
9+
* @param {string} key ASCII only
10+
* @param {number} seed Positive integer only
11+
* @return {number} 32-bit positive integer hash
12+
*/
13+
14+
export function murmurhash3_32_gc(key, seed) {
15+
var remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i;
16+
17+
remainder = key.length & 3; // key.length % 4
18+
bytes = key.length - remainder;
19+
h1 = seed;
20+
c1 = 0xcc9e2d51;
21+
c2 = 0x1b873593;
22+
i = 0;
23+
24+
while (i < bytes) {
25+
k1 =
26+
((key.charCodeAt(i) & 0xff)) |
27+
((key.charCodeAt(++i) & 0xff) << 8) |
28+
((key.charCodeAt(++i) & 0xff) << 16) |
29+
((key.charCodeAt(++i) & 0xff) << 24);
30+
++i;
31+
32+
k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;
33+
k1 = (k1 << 15) | (k1 >>> 17);
34+
k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;
35+
36+
h1 ^= k1;
37+
h1 = (h1 << 13) | (h1 >>> 19);
38+
h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;
39+
h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));
40+
}
41+
42+
k1 = 0;
43+
44+
switch (remainder) {
45+
case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
46+
case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
47+
case 1: k1 ^= (key.charCodeAt(i) & 0xff);
48+
49+
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
50+
k1 = (k1 << 15) | (k1 >>> 17);
51+
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
52+
h1 ^= k1;
53+
}
54+
55+
h1 ^= key.length;
56+
57+
h1 ^= h1 >>> 16;
58+
h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
59+
h1 ^= h1 >>> 13;
60+
h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;
61+
h1 ^= h1 >>> 16;
62+
63+
return h1 >>> 0;
64+
}

0 commit comments

Comments
 (0)