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:
16At 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 trueCommon 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).