Last active
June 29, 2022 23:16
-
-
Save cgiosy/f85c934d5c989cc000ddbf2abdf79ac9 to your computer and use it in GitHub Desktop.
XXHash32 JS Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getUint32 = (arr: Uint8Array, i: number) => ( | |
arr[i] | arr[i + 1 | 0] << 8 | arr[i + 2 | 0] << 16 | arr[i + 3 | 0] << 24 | |
); | |
const rotl32 = (x: number, r: number) => (x << r) | (x >>> 32 - r); | |
const xxh32 = (buf: Uint8Array, seed = 0) => { | |
seed |= 0; | |
const len = buf.length | 0; | |
let i = 0; | |
let h = (seed + len | 0) + 0x165667B1 | 0; | |
if (len < 16) { | |
for (; (i + 3 | 0) < len; i = i + 4 | 0) | |
h = Math.imul(rotl32(h + Math.imul(getUint32(buf, i), 0xC2B2AE3D) | 0, 17), 0x27D4EB2F); | |
} else { | |
let v0 = seed + 0x24234428 | 0; | |
let v1 = seed + 0x85EBCA77 | 0; | |
let v2 = seed; | |
let v3 = seed - 0x9E3779B1 | 0; | |
if (len < 256) { | |
for (; (i + 15 | 0) < len; i = i + 16 | 0) { | |
v0 = Math.imul(rotl32(v0 + Math.imul(getUint32(buf, i + 0 | 0), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v1 = Math.imul(rotl32(v1 + Math.imul(getUint32(buf, i + 4 | 0), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v2 = Math.imul(rotl32(v2 + Math.imul(getUint32(buf, i + 8 | 0), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v3 = Math.imul(rotl32(v3 + Math.imul(getUint32(buf, i + 12 | 0), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
} | |
h = (((rotl32(v0, 1) + rotl32(v1, 7) | 0) + rotl32(v2, 12) | 0) + rotl32(v3, 18) | 0) + len | 0; | |
for (; (i + 3 | 0) < len; i = i + 4 | 0) | |
h = Math.imul(rotl32(h + Math.imul(getUint32(buf, i), 0xC2B2AE3D) | 0, 17), 0x27D4EB2F); | |
} else { | |
const view = new DataView(buf.buffer); | |
for (; (i + 15 | 0) < len; i = i + 16 | 0) { | |
v0 = Math.imul(rotl32(v0 + Math.imul(view.getUint32(i + 0 | 0, true), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v1 = Math.imul(rotl32(v1 + Math.imul(view.getUint32(i + 4 | 0, true), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v2 = Math.imul(rotl32(v2 + Math.imul(view.getUint32(i + 8 | 0, true), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
v3 = Math.imul(rotl32(v3 + Math.imul(view.getUint32(i + 12 | 0, true), 0x85EBCA77) | 0, 13), 0x9E3779B1); | |
} | |
h = (((rotl32(v0, 1) + rotl32(v1, 7) | 0) + rotl32(v2, 12) | 0) + rotl32(v3, 18) | 0) + len | 0; | |
for (; (i + 3 | 0) < len; i = i + 4 | 0) | |
h = Math.imul(rotl32(h + Math.imul(view.getUint32(i, true), 0xC2B2AE3D) | 0, 17), 0x27D4EB2F); | |
} | |
} | |
for (; i < len; i = i + 1 | 0) | |
h = Math.imul(rotl32(h + Math.imul(buf[i], 0x165667B1) | 0, 11), 0x9E3779B1); | |
h = Math.imul(h ^ h >>> 15, 0x85EBCA77); | |
h = Math.imul(h ^ h >>> 13, 0xC2B2AE3D); | |
return (h ^ h >>> 16) >>> 0; | |
}; | |
export default xxh32; |
Benchmark
# Throughput - 16 bytes
xxh32.js: 233.05165950866152 MB/s
hash-wasm.xxhash32: 65.2451403877805 MB/s
hash-wasm.xxhash64: 33.463045859622625 MB/s
hash-wasm.xxhash128: 26.104324164081667 MB/s
hash-wasm.xxhash3: 33.16877614561841 MB/s
hash-wasm.crc32: 60.72135141026678 MB/s
hash-wasm.blake3: 20.083299196822654 MB/s
hash-wasm.sha1: 21.31338591657368 MB/s
hash-wasm.sha256: 17.204622334383593 MB/s
hash-wasm.sha512: 10.519422118677038 MB/s
hash-wasm.sha3: 10.87381065579847 MB/s
hash-wasm.md5: 26.94183066115019 MB/s
# Throughput - 256 bytes
xxh32.js: 1459.0742013673616 MB/s
hash-wasm.xxhash32: 912.3366422516513 MB/s
hash-wasm.xxhash64: 555.7804742286385 MB/s
hash-wasm.xxhash128: 435.8167534892718 MB/s
hash-wasm.xxhash3: 522.0287774049153 MB/s
hash-wasm.crc32: 677.6684432194427 MB/s
hash-wasm.blake3: 278.8266499607441 MB/s
hash-wasm.sha1: 241.16285718396705 MB/s
hash-wasm.sha256: 160.20225160477395 MB/s
hash-wasm.sha512: 136.34390737987852 MB/s
hash-wasm.sha3: 123.41993041591684 MB/s
hash-wasm.md5: 255.2523216864908 MB/s
# Throughput - 4096 bytes
xxh32.js: 5825.412345695758 MB/s
hash-wasm.xxhash32: 4824.87418061821 MB/s
hash-wasm.xxhash64: 5295.7885934688375 MB/s
hash-wasm.xxhash128: 4183.324814999695 MB/s
hash-wasm.xxhash3: 4639.759417730065 MB/s
hash-wasm.crc32: 1775.2268904489122 MB/s
hash-wasm.blake3: 750.7761200245818 MB/s
hash-wasm.sha1: 678.8332389393644 MB/s
hash-wasm.sha256: 326.52230774914324 MB/s
hash-wasm.sha512: 479.2395482756276 MB/s
hash-wasm.sha3: 297.6650603055725 MB/s
hash-wasm.md5: 486.35204339833297 MB/s
# Throughput - 65536 bytes
xxh32.js: 7117.317183501204 MB/s
hash-wasm.xxhash32: 6217.269224283 MB/s
hash-wasm.xxhash64: 10626.99709827573 MB/s
hash-wasm.xxhash128: 8502.518078010455 MB/s
hash-wasm.xxhash3: 8641.513626457921 MB/s
hash-wasm.crc32: 1963.6240093152837 MB/s
hash-wasm.blake3: 811.5914462901178 MB/s
hash-wasm.sha1: 760.5687346096273 MB/s
hash-wasm.sha256: 345.45550246387756 MB/s
hash-wasm.sha512: 546.3248935564654 MB/s
hash-wasm.sha3: 318.26581203555975 MB/s
hash-wasm.md5: 513.8385025591177 MB/s
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
xxh32(new TextEncoder().encode("test"))
Size: Minified < 1.6kb, Gzip < 0.5kb