#!/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()); }