|
2 | 2 | // This product includes software developed at Datadog (https://www.datadoghq.com/). |
3 | 3 | // Copyright 2019-Present Datadog, Inc. |
4 | 4 |
|
5 | | -import { createHash } from 'crypto'; |
| 5 | +import xxhash from 'xxhash-wasm'; |
| 6 | +import type { XXHashAPI } from 'xxhash-wasm'; |
6 | 7 |
|
7 | 8 | const VARIANT_CHARS = ['8', '9', 'a', 'b'] as const; |
| 9 | +// Arbitrary fixed seed so the second half is independent from the first (which uses the default seed). |
| 10 | +const SECOND_HALF_SEED = BigInt('0x9e3779b97f4a7c15'); |
8 | 11 |
|
9 | | -// SHA-256(input) truncated to 128 bits → deterministic UUID-v4-shaped identifier. |
10 | | -// SHA-256 is used instead of MD5 for FIPS 140-2/3 compliance. |
| 12 | +let hasher: XXHashAPI | undefined; |
| 13 | + |
| 14 | +// Must be awaited (e.g. during a build's `buildStart`) before any synchronous `stringToUUID` call. |
| 15 | +export const initDebugIdHasher = async (): Promise<void> => { |
| 16 | + hasher = hasher ?? (await xxhash()); |
| 17 | +}; |
| 18 | + |
| 19 | +// xxHash64(input) || xxHash64(input, seed) → 128 bits, reshaped into a deterministic UUID-v4-shaped identifier. |
| 20 | +// xxHash instead of a cryptographic hash: debug IDs only need to be deterministic and cheap to compute. |
11 | 21 | export const stringToUUID = (input: string): string => { |
12 | | - const hash = createHash('sha256').update(input).digest('hex').slice(0, 32); |
| 22 | + if (!hasher) { |
| 23 | + throw new Error('[stringToUUID] Hasher not initialized: call `initDebugIdHasher()` first.'); |
| 24 | + } |
| 25 | + const firstHalf = hasher.h64(input).toString(16).padStart(16, '0'); |
| 26 | + const secondHalf = hasher.h64(input, SECOND_HALF_SEED).toString(16).padStart(16, '0'); |
| 27 | + const hash = `${firstHalf}${secondHalf}`; |
13 | 28 | const withVersion = `${hash.slice(0, 12)}4${hash.slice(13)}`; |
14 | 29 | const variantIndex = withVersion.charCodeAt(16) % 4; |
15 | 30 | const withVariant = `${withVersion.slice(0, 16)}${VARIANT_CHARS[variantIndex]}${withVersion.slice(17)}`; |
|
0 commit comments