The docs explain the collision maths, but users can't compute it for their own configuration.
Three pure functions would make it usable, taking the same options and defaults as createId
(size 24, base62):
entropyBits(options?: IdOptions): number
sizeForEntropy(bits: number, alphabet?: string): number
collisionProbability(count: number, options?: IdOptions): number
So createId({ size: sizeForEntropy(128) }) replaces guesswork, and
collisionProbability(1e9) answers "is the default safe for us?"
The trap: floating-point precision
The textbook formula 1 - Math.exp(-n²/2N) returns exactly 0 for realistic inputs, because
Math.exp(-4.8e-26) rounds to 1. Compute it in log space and use Math.expm1:
const x = Math.exp(Math.log(n) + Math.log(n - 1) - Math.LN2 - size * Math.log(alphabetLength));
return -Math.expm1(-x);
Reference values for tests
| call |
expected |
entropyBits() |
≈ 142.90 |
entropyBits({ size: 8 }) |
≈ 47.63 |
sizeForEntropy(128) |
22 |
collisionProbability(1e9) |
≈ 4.804e-26 |
collisionProbability(1e6, { size: 8 }) |
≈ 2.287e-3 |
Acceptance criteria
- New
src/utils/entropy.ts, exported from src/index.ts
- The reference values above as tests, plus
count < 2 returning 0 and input validation
(alphabet of at least 2 characters, positive integer size, non-negative count)
- Results agree with the "Uniqueness & Collisions" docs page
- CHANGELOG entry under
Unreleased; npm run verify passes; no inline comments in src/
The docs explain the collision maths, but users can't compute it for their own configuration.
Three pure functions would make it usable, taking the same options and defaults as
createId(size 24, base62):
So
createId({ size: sizeForEntropy(128) })replaces guesswork, andcollisionProbability(1e9)answers "is the default safe for us?"The trap: floating-point precision
The textbook formula
1 - Math.exp(-n²/2N)returns exactly 0 for realistic inputs, becauseMath.exp(-4.8e-26)rounds to 1. Compute it in log space and useMath.expm1:Reference values for tests
entropyBits()entropyBits({ size: 8 })sizeForEntropy(128)collisionProbability(1e9)collisionProbability(1e6, { size: 8 })Acceptance criteria
src/utils/entropy.ts, exported fromsrc/index.tscount < 2returning0and input validation(alphabet of at least 2 characters, positive integer size, non-negative count)
Unreleased;npm run verifypasses; no inline comments insrc/