Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to generate a random password

Short answer

Take random bytes from crypto.getRandomValues() and turn each one into a character of the set:

const generatePassword = (length = 16) => {
  const chars = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%&*';
  const values = crypto.getRandomValues(new Uint32Array(length));
  return Array.from(values, (value) => chars[value % chars.length]).join('');
};
 
const password = generatePassword();
console.log(password.length);

Output:

16

At least one character of each group

Take one character from each group, fill the rest from all characters, and shuffle the result:

const groups = ['abcdefghijkmnopqrstuvwxyz', 'ABCDEFGHJKLMNPQRSTUVWXYZ', '23456789', '!@#$%&*'];
const randomIndex = (max) => crypto.getRandomValues(new Uint32Array(1))[0] % max;
const pick = (set) => set[randomIndex(set.length)];
 
const generatePassword = (length = 12) => {
  const all = groups.join('');
  const chars = groups.map(pick);
  while (chars.length < length) chars.push(pick(all));
  for (let i = chars.length - 1; i > 0; i--) {
    const j = randomIndex(i + 1);
    [chars[i], chars[j]] = [chars[j], chars[i]];
  }
  return chars.join('');
};
 
const password = generatePassword();
console.log(password.length, groups.every((set) => [...password].some((char) => set.includes(char))));

Output:

12 true

Common mistake

Math.random() is not meant for secrets: its sequence can be predicted. For passwords, tokens and codes, always use crypto.

// not for passwords
const weak = Math.random().toString(36).slice(2);

Functions used in this recipe

  • Array.from — Creates an array from a string, Set, Map or another iterable.
  • crypto.randomUUID — Creates a random unique identifier (UUID).

Thanks for reading!

Donate to the site — we work hard for you.