source dump of claude code
at main 46 lines 1.7 kB view raw
1/** 2 * djb2 string hash — fast non-cryptographic hash returning a signed 32-bit int. 3 * Deterministic across runtimes (unlike Bun.hash which uses wyhash). Use as a 4 * fallback when Bun.hash isn't available, or when you need on-disk-stable 5 * output (e.g. cache directory names that must survive runtime upgrades). 6 */ 7export function djb2Hash(str: string): number { 8 let hash = 0 9 for (let i = 0; i < str.length; i++) { 10 hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0 11 } 12 return hash 13} 14 15/** 16 * Hash arbitrary content for change detection. Bun.hash is ~100x faster than 17 * sha256 and collision-resistant enough for diff detection (not crypto-safe). 18 */ 19export function hashContent(content: string): string { 20 if (typeof Bun !== 'undefined') { 21 return Bun.hash(content).toString() 22 } 23 // eslint-disable-next-line @typescript-eslint/no-require-imports 24 const crypto = require('crypto') as typeof import('crypto') 25 return crypto.createHash('sha256').update(content).digest('hex') 26} 27 28/** 29 * Hash two strings without allocating a concatenated temp string. Bun path 30 * seed-chains wyhash (hash(a) feeds as seed to hash(b)); Node path uses 31 * incremental SHA-256 update. Seed-chaining naturally disambiguates 32 * ("ts","code") vs ("tsc","ode") so no separator is needed under Bun. 33 */ 34export function hashPair(a: string, b: string): string { 35 if (typeof Bun !== 'undefined') { 36 return Bun.hash(b, Bun.hash(a)).toString() 37 } 38 // eslint-disable-next-line @typescript-eslint/no-require-imports 39 const crypto = require('crypto') as typeof import('crypto') 40 return crypto 41 .createHash('sha256') 42 .update(a) 43 .update('\0') 44 .update(b) 45 .digest('hex') 46}