Small project, one professional detail that impresses: real randomness.
The generator
const SETS = {
lower: "abcdefghijklmnopqrstuvwxyz",
upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
digits: "0123456789",
symbols: "!@#$%^&*()-_=+[]{};:,.?",
};
function generate(length = 16, opts = { lower: true, upper: true, digits: true, symbols: true }) {
const pool = Object.keys(opts).filter(k => opts[k]).map(k => SETS[k]).join("");
const rand = new Uint32Array(length);
crypto.getRandomValues(rand); // โ
cryptographic randomness
return [...rand].map(n => pool[n % pool.length]).join("");
}Why not Math.random()? It's predictable โ fine for games, wrong for secrets. crypto.getRandomValues is the browser's CSPRNG. Knowing the difference is the interview-grade detail.
The strength meter
function strength(pw) {
let s = 0;
if (pw.length >= 12) s++;
if (/[a-z]/.test(pw) && /[A-Z]/.test(pw)) s++;
if (/\d/.test(pw)) s++;
if (/[^a-zA-Z0-9]/.test(pw)) s++;
return ["Weak", "Fair", "Good", "Strong", "Excellent"][s];
}Add a length slider (input type="range"), checkboxes per set, the copy button with feedback, and a regenerate animation. Two hours, ships today โ build it in the Playground.