Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 8x 8x 754x 754x 754x 754x 754x 754x 754x 1690x 754x 754x 432x 80x 352x 754x | /**
* Password strength estimation based on character-pool entropy.
*
* Computes entropy as length × log2(poolSize), where poolSize is determined
* by the character classes present. This naturally rewards length over
* character diversity — a long lowercase passphrase scores higher than a
* short symbol-laden password.
*/
export interface PasswordStrength {
score: number; // 0–4 (0 = empty)
label: string;
color: string;
textColor: string;
bits: number;
}
const EMPTY: PasswordStrength = { score: 0, label: "", color: "", textColor: "", bits: 0 };
const LEVELS: Record<number, { label: string; color: string; textColor: string }> = {
1: { label: "Weak", color: "bg-red-500", textColor: "text-red-500" },
2: { label: "Fair", color: "bg-orange-500", textColor: "text-orange-500" },
3: { label: "Good", color: "bg-yellow-500", textColor: "text-yellow-500" },
4: { label: "Strong", color: "bg-green-500", textColor: "text-green-500" },
};
/**
* Estimate character-pool entropy: length × log2(poolSize).
*/
function charEntropy(password: string): number {
let poolSize = 0;
Eif (/[a-z]/.test(password)) poolSize += 26;
if (/[A-Z]/.test(password)) poolSize += 26;
if (/[0-9]/.test(password)) poolSize += 10;
if (/[^a-zA-Z0-9]/.test(password)) poolSize += 33;
Iif (poolSize === 0) poolSize = 95;
return password.length * Math.log2(poolSize);
}
/**
* Get password strength based on character-pool entropy.
*
* Thresholds (in bits of entropy):
* < 40 → Weak
* 40–59 → Fair
* 60–79 → Good
* 80+ → Strong
*/
export function getPasswordStrength(password: string): PasswordStrength {
if (password.length === 0) return EMPTY;
const bits = charEntropy(password);
let score: number;
if (bits < 40) score = 1;
else if (bits < 60) score = 2;
else if (bits < 80) score = 3;
else score = 4;
// biome-ignore lint/style/noNonNullAssertion: score is clamped to valid range
return { score, bits, ...LEVELS[score]! };
}
|