Skip to content

Commit e48e8ae

Browse files
author
ferris
committedJan 21, 2025
Fix XXH64 short-lengths
1 parent 291ca8e commit e48e8ae

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed
 

‎test_vectors.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import xxhash
2+
import subprocess
3+
import secrets
4+
5+
# test_str = "WAIDHOAWDHOAWIDHAOWIDHIOAIWODHAOWIDHAOWIDHOAIWHDOAIHWDOIAWHDOIAHWDOIAHWDOIHAWODIHAWODIHAWODIHA"
6+
7+
for len in [2, 6, 12, 18, 32+18, 64, 96]:
8+
test_str = secrets.token_hex(len)
9+
10+
local_xxh64_hash = xxhash.xxh64_intdigest(test_str.encode())
11+
local_xxh3_128_hash = xxhash.xxh3_128_intdigest(test_str.encode())
12+
13+
ref_xxh3_128_hash = int(subprocess.check_output(["node", "-e", "const { XXH3_128 } = require('./xxh3.js'); console.log(XXH3_128(Buffer.from(\"%s\")).toString(10))" % test_str]).strip())
14+
ref_xxh64_hash = int(subprocess.check_output(["node", "-e", "const { XXH64 } = require('./xxh64.js'); console.log(XXH64(Buffer.from(\"%s\")).toString(10))" % test_str]).strip())
15+
16+
xxh64_res = '✅' if local_xxh64_hash == ref_xxh64_hash else f"xxh64 not eq to ref, {local_xxh64_hash=} != {ref_xxh64_hash=}"
17+
print(f'[ALGO=XXH64, LEN={len}]: {xxh64_res}')
18+
19+
xxh3_128_res = '✅' if local_xxh3_128_hash == ref_xxh3_128_hash else f"xxh3_128 not eq to ref, {local_xxh3_128_hash=} != {ref_xxh3_128_hash=}"
20+
print(f'[ALGO=XXH3_128, LEN={len}]: {xxh3_128_res}')

‎xxh3.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
if (!(globalThis as any).Buffer) {
2-
(globalThis as any).Buffer = require('buffer/').Buffer;
3-
}
1+
// if (!(globalThis as any).Buffer) {
2+
// (globalThis as any).Buffer = require('buffer/').Buffer;
3+
// }
44

55
const n = (n: number | string) => BigInt(n)
66
const PRIME64_1 = n('0x9E3779B185EBCA87'); /* 0b1001111000110111011110011011000110000101111010111100101010000111 */
@@ -9,6 +9,7 @@ const PRIME64_3 = n('0x165667B19E3779F9'); /* 0b000101100101011001100111101100
99
const PRIME64_4 = n('0x85EBCA77C2B2AE63'); /* 0b1000010111101011110010100111011111000010101100101010111001100011 */
1010
const PRIME64_5 = n('0x27D4EB2F165667C5');
1111
const kkey = Buffer.from('b8fe6c3923a44bbe7c01812cf721ad1cded46de9839097db7240a4a4b7b3671fcb79e64eccc0e578825ad07dccff7221b8084674f743248ee03590e6813a264c3c2852bb91c300cb88d0658b1b532ea371644897a20df94e3819ef46a9deacd8a8fa763fe39c343ff9dcbbc7c70b4f1d8a51e04bcdb45931c89f7ec9d9787364eac5ac8334d3ebc3c581a0fffa1363eb170ddd51b7f0da49d316552629d4689e2b16be587d47a1fc8ff8b8d17ad031ce45cb3a8f95160428afd7fbcabb4b407e', 'hex')
12+
const mask128 = (n(1) << n(128)) - n(1);
1213
const mask64 = (n(1) << n(64)) - n(1);
1314
const mask32 = (n(1) << n(32)) - n(1);
1415
const STRIPE_LEN = 64
@@ -117,14 +118,14 @@ function XXH3_hashLong_128b(data: Buffer, seed: bigint) {
117118

118119

119120
function XXH3_mul128(a: bigint, b: bigint) {
120-
const lll = a * b;
121+
const lll = (a * b) & mask128;
121122
return (lll + (lll >> n(64))) & mask64;
122123
}
123124

124125
function XXH3_mix16B(data: Buffer, key: Buffer) {
125126
return XXH3_mix2Accs(data, key)
126-
// return XXH3_mul128(data.readBigUInt64LE(data_offset) ^ key.readBigUInt64LE(key_offset),
127-
// data.readBigUInt64LE(data_offset + 8) ^ key.readBigUInt64LE(key_offset + 8));
127+
// return XXH3_mul128(data.readBigUInt64LE(0) ^ key.readBigUInt64LE(0),
128+
// data.readBigUInt64LE(8) ^ key.readBigUInt64LE(8));
128129
}
129130

130131
function XXH3_avalanche(h64: bigint) {
@@ -223,4 +224,4 @@ export function XXH3_128(data: Buffer, seed: bigint = n(0)) {
223224
const part2 = ((acc1 * PRIME64_3) + (acc2 * PRIME64_4) + ((n(len) - seed) * PRIME64_2)) & mask64;
224225

225226
return (XXH3_avalanche(part1) << n(64)) | XXH3_avalanche(part2)
226-
}
227+
}

‎xxh64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ function XH64_mix(acc: bigint) {
9898

9999
function XXH64_small(data: Buffer, seed: bigint) {
100100
let acc = (seed + PRIME64_5) & mask64;
101+
acc += n(data.byteLength);
101102
acc = XH64_accumulateRemainder(data, acc)
102103
return XH64_mix(acc)
103104
}
@@ -113,4 +114,4 @@ export function XXH64(data: Buffer, seed: bigint = n(0)) {
113114
])
114115

115116
return XH64_accumulate(data, acc)
116-
}
117+
}

0 commit comments

Comments
 (0)
Please sign in to comment.