diff options
Diffstat (limited to 'bin/random-id.ts')
| -rwxr-xr-x | bin/random-id.ts | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/bin/random-id.ts b/bin/random-id.ts new file mode 100755 index 0000000..b8bf364 --- /dev/null +++ b/bin/random-id.ts @@ -0,0 +1,105 @@ +#!/usr/bin/env node --disable-warning=DEP0180 --no-warnings + +const idChars = (function (): string[] { + const chars: string[] = []; + + function code(x: string | number): number { + return typeof x === "string" ? x.charCodeAt(0) : x; + } + + function add(from: string | number, to: string | number): void { + const fromCode = code(from); + const toCode = code(to); + for (let c = fromCode; c <= toCode; ++c) { + chars.push(String.fromCharCode(c)); + } + } + + add("0", "9"); + add("a", "z"); + add("A", "Z"); + return chars; +})(); + + +/* +Alphabet size: 62 characters (A–Z, a–z, 0–9) +Total possible IDs of length n: TOTAL_IDS = 62^n +To compute the probability that two randomly generated IDs collide (i.e., are identical): P_COLLISION = 1 / TOTAL_IDS + +========================================================== + ID Length | ID space | P(Collision) | Intuition +-----------|----------------|----------------|------------ + 5 | 916,132,832 | ~1.09 × 10⁻⁹ | ~1 in a billion (like lottery odds) + 6 | 56,800,235,584 | ~1.76 × 10⁻¹¹ | ~1 in 50 billion (world population × 6) + 17 | 2.96 × 10³⁰ | ~3.38 × 10⁻³¹ | ~1 in a nonillion (grains of sand × 10¹⁹) +========================================================== + +Interpretation: +- At **length 5**, collisions are rare but not implausible if generating millions of IDs. +- At **length 6**, collisions are extremely rare - safe for most casual uses. +- At **length 17**, collisions are cosmically unlikely—about as probable as picking the same atom out of all atoms in the solar system. + +========================================================== +== Out of a pool of 100,000 === + +Alphabet size: 62 characters (A–Z, a–z, 0–9) +Existing IDs: N = 100 000 + +Formulas: + TOTAL_IDS(n) = 62^n + P_match_one = 1 / TOTAL_IDS(n) + P_collision_any = 1 − (1 − P_match_one)^N + +-------------------------------------------------------------------------------- + n | TOTAL_IDS(n) | P_collision_any | Intuition +---+----------------------+--------------------------------+------------------------------------------- + 5 | 62^5 = 916 132 832 | 1 − (1 − 1/916 132 832)^100 000 + | | ≈ 1.09 × 10⁻⁴ | ~0.01% → ~1 in 9 200 + | | | (about as rare as drawing the same + | | | lottery number in ~9 200 draws) + + 6 | 62^6 = 56 800 235 584| ≈ 1.76 × 10⁻⁶ | ~0.000176% → ~1 in 568 000 + | | | (like finding a specific LEGO + | | | brick in a pile of half a million) + + 8 | 62^8 ≈ 2.18 × 10^14 | ≈ 4.58 × 10⁻¹⁰ | ~4.6 × 10⁻⁸% → ~1 in 2.2 billion + | | | (on par with winning a major lottery) + +17 | 62^17 ≈ 2.96 × 10^30 | ≈ 3.38 × 10⁻²⁶ | ~3.4 × 10⁻²⁴% → ~1 in 3 × 10^25 + | | | (effectively zero—astronomically + | | | unlikely, far beyond grains of sand + | | | on every beach on Earth) +-------------------------------------------------------------------------------- + +Reasoning: +- TOTAL_IDS(n) counts all possible length-n strings. +- P_match_one = chance it matches one given ID. +- With N existing, P_collision_any = 1 minus the chance it misses all N. +- For n=5 collisions are possible if you generate many IDs; for n≥8 they're vanishingly rare; for n=17 they're effectively impossible in any realistic system. + + */ + +// With 62 possible chars, a 17 char long ID has about 10^30 possible values, +// the chance of finding any of 8 billion of them is about the same as the +// chance of finding a single specific grain of sand in on earth. +// +const idLength = process.env.ID_LENGTH ? parseInt(process.env.ID_LENGTH) :17; + +function randomId(length: number = idLength): string { + const chars: string[] = []; + for (let i = 0; i < length; ++i) { + const c = Math.floor(Math.random() * idChars.length); + chars.push(idChars[c]!); + } + return chars.join(""); +} + +// take count from from first argument, default to 1 +const count = parseInt(process.argv[2] || "1"); + +// execute and print +for (let i = 0; i < count; ++i) { + console.log(randomId()); +} + |
