From e64da0f32c9619ca6d995577e31db16dc7cee6ef Mon Sep 17 00:00:00 2001 From: Alex Kern Date: Sun, 30 Mar 2025 21:14:45 -0700 Subject: [PATCH] Improves random generation (#251) --- src/channel.ts | 2 +- src/slugs.ts | 32 +++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/channel.ts b/src/channel.ts index c22c352..d2fc79d 100644 --- a/src/channel.ts +++ b/src/channel.ts @@ -38,7 +38,7 @@ async function generateShortSlugUntilUnique( checkExists: (key: string) => Promise, ): Promise { for (let i = 0; i < config.shortSlug.maxAttempts; i++) { - const slug = generateShortSlug() + const slug = await generateShortSlug() const exists = await checkExists(getShortSlugKey(slug)) if (!exists) { return slug diff --git a/src/slugs.ts b/src/slugs.ts index 5e4aa00..1ce6e35 100644 --- a/src/slugs.ts +++ b/src/slugs.ts @@ -25,12 +25,17 @@ function generateRandomWords( } const getRandomInt = (max: number): number => { - const buffer = new Uint32Array(1) - if (typeof window !== 'undefined' && window.crypto) { - window.crypto.getRandomValues(buffer) - } else { - crypto.randomFillSync(buffer) - } + const limit = 4294967295 - (4294967295 % max) // uint32 max + + let buffer = new Uint32Array(1) + do { + if (typeof window !== 'undefined' && window.crypto) { + window.crypto.getRandomValues(buffer) + } else { + crypto.randomFillSync(buffer) + } + } while (buffer[0] >= limit) + return buffer[0] % max } @@ -44,15 +49,12 @@ function generateRandomWords( }) } -export const generateShortSlug = (): string => { - let result = '' - for (let i = 0; i < config.shortSlug.numChars; i++) { - result += - config.shortSlug.chars[ - Math.floor(Math.random() * config.shortSlug.chars.length) - ] - } - return result +export const generateShortSlug = async (): Promise => { + const parts = await generateRandomWords( + config.shortSlug.chars.split(''), + config.shortSlug.numChars, + ) + return parts.join('') } export const generateLongSlug = async (): Promise => {