47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
/**
|
|
* djb2 string hash — fast non-cryptographic hash returning a signed 32-bit int.
|
|
* Deterministic across runtimes (unlike Bun.hash which uses wyhash). Use as a
|
|
* fallback when Bun.hash isn't available, or when you need on-disk-stable
|
|
* output (e.g. cache directory names that must survive runtime upgrades).
|
|
*/
|
|
export function djb2Hash(str: string): number {
|
|
let hash = 0
|
|
for (let i = 0; i < str.length; i++) {
|
|
hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0
|
|
}
|
|
return hash
|
|
}
|
|
|
|
/**
|
|
* Hash arbitrary content for change detection. Bun.hash is ~100x faster than
|
|
* sha256 and collision-resistant enough for diff detection (not crypto-safe).
|
|
*/
|
|
export function hashContent(content: string): string {
|
|
if (typeof Bun !== 'undefined') {
|
|
return Bun.hash(content).toString()
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const crypto = require('crypto') as typeof import('crypto')
|
|
return crypto.createHash('sha256').update(content).digest('hex')
|
|
}
|
|
|
|
/**
|
|
* Hash two strings without allocating a concatenated temp string. Bun path
|
|
* seed-chains wyhash (hash(a) feeds as seed to hash(b)); Node path uses
|
|
* incremental SHA-256 update. Seed-chaining naturally disambiguates
|
|
* ("ts","code") vs ("tsc","ode") so no separator is needed under Bun.
|
|
*/
|
|
export function hashPair(a: string, b: string): string {
|
|
if (typeof Bun !== 'undefined') {
|
|
return Bun.hash(b, Bun.hash(a)).toString()
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
const crypto = require('crypto') as typeof import('crypto')
|
|
return crypto
|
|
.createHash('sha256')
|
|
.update(a)
|
|
.update('\0')
|
|
.update(b)
|
|
.digest('hex')
|
|
}
|