功能说明
estimatePasswordStrength 根据密码使用的字符种类估算搜索空间,结合去重后的有效长度计算熵值,并对常见弱口令、键盘序列和连续重复字符打折。结果包含熵位数、零到四的评分、标签、字符池大小、长度与唯一字符数,适合注册与修改密码表单的即时提示,也可用于后台弱口令巡检。
关键代码
函数依次检测小写字母、大写字母、数字和符号,累加对应字符池大小,再用有效长度乘 log2 得到理论熵。有效长度取唯一字符数与实际长度四分之三中的较大值,降低 aaaaaa 这类重复串的收益。命中 123456、password、qwerty 或三连重复时熵减半,长度不足八位再乘 0.6。评分按二十、四十、六十、八十分档。
使用注意
这是启发式估算,不等同于 zxcvbn 等基于泄露字典的评估,不能替代服务端强度策略。熵高不代表未被泄露,注册流程仍应检查泄露密码库并强制多因素认证。函数在浏览器执行,密码字符串会短暂存在于内存,不要记录到日志或分析事件。评分只用于提示,最终是否允许提交应由明确规则决定。
验证方式
用 password、P@ssw0rd!、随机十六位字符串、纯数字长串和空串验证评分梯度。测试三连重复与键盘序列会降低熵,唯一字符少的重复串得分更低。检查返回值字段完整、熵为整数、评分在零到四之间。再覆盖非字符串输入被转成字符串的行为,并确认空密码返回 very weak 且不抛错。
代码示例
const COMMON_PATTERNS = [/^123456/, /password/i, /qwerty/i, /(.)\1{2,}/];
// Password strength estimation based on character-pool entropy.
export function estimatePasswordStrength(password) {
const value = String(password);
const pools = [
[/[a-z]/, 26],
[/[A-Z]/, 26],
[/[0-9]/, 10],
[/[^A-Za-z0-9]/, 33],
];
const poolSize = pools.reduce((total, [pattern, size]) => {
return total + (pattern.test(value) ? size : 0);
}, 0);
const unique = new Set(value).size;
const effectiveLength = Math.max(unique, Math.ceil(value.length * 0.75));
let entropyBits = poolSize > 0 ? effectiveLength * Math.log2(poolSize) : 0;
for (const pattern of COMMON_PATTERNS) {
if (pattern.test(value)) entropyBits *= 0.5;
}
if (value.length < 8) entropyBits *= 0.6;
const thresholds = [20, 40, 60, 80];
let score = thresholds.filter((threshold) => entropyBits >= threshold).length;
if (value.length === 0) score = 0;
const labels = ["very weak", "weak", "fair", "strong", "very strong"];
return {
entropyBits: Math.round(entropyBits),
score,
label: labels[score],
poolSize,
length: value.length,
uniqueCharacters: unique,
};
}