Skip to content

Instantly share code, notes, and snippets.

@wlib
Created June 12, 2025 03:08
Show Gist options
  • Save wlib/3808b775bcfd7871cc9bcf25b64ccb8a to your computer and use it in GitHub Desktop.
Save wlib/3808b775bcfd7871cc9bcf25b64ccb8a to your computer and use it in GitHub Desktop.

Revisions

  1. wlib created this gist Jun 12, 2025.
    33 changes: 33 additions & 0 deletions makeRandomPassword.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    const basicLatin = String.fromCharCode(...range(32, 127))

    const makeRandomPassword = ({
    length = 32,
    characters = basicLatin
    }: {
    /** Max 256 */
    length?: number,
    characters?: string | ReadonlyArray<string>
    } = {}) => {
    const entropyPerCharacter = 8
    const statesPerCharacter = 2 ** entropyPerCharacter

    if (characters.length > statesPerCharacter)
    throw new Error(`Character count (${characters.length}) must not exceed 2^8 (256)`)

    const limit = statesPerCharacter - (statesPerCharacter % characters.length)

    const randomValuesUnderLimit: number[] = []
    while (randomValuesUnderLimit.length < length) {
    const randomValues = crypto.getRandomValues(
    new Uint8Array(length - randomValuesUnderLimit.length)
    )
    for (const randomValue of randomValues)
    if (randomValue < limit)
    randomValuesUnderLimit.push(randomValue)
    }

    let result = ""
    for (const n of randomValuesUnderLimit)
    result += characters[n % characters.length]
    return result
    }