summaryrefslogtreecommitdiff
path: root/bin/random-id.ts
diff options
context:
space:
mode:
Diffstat (limited to 'bin/random-id.ts')
-rwxr-xr-xbin/random-id.ts105
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());
+}
+