密码复杂度检查方案(标准可落地版)
适用场景:账号注册、密码重置、运维系统、LDAP/Radius、Web 后台;可直接翻译成伪代码、Python/C++ 实现。 设计思路:分层校验(基础规则 + 强度评分 + 黑名单),支持灵活开关规则,输出结构化结果(是否通过、强度等级、不满足项)。
一、核心定义
字符分类
- 大写字母
A-Z - 小写字母
a-z - 数字
0-9 - 特殊符号:
!@#$%^&*()_+-=[]{}|;:,.<>?(可自定义,建议排除易混淆、命令注入风险字符如" ' \)
注意:中文、全角字符默认归为其他字符,不计入 4 类字符集,但可计入长度。
二、规则集(推荐企业标准,可分【基础版】【严格版】)
✅ 基础版(内网普通业务,最低安全)
- 长度 ≥8
- 至少包含 2 种 上面 4 类字符
- 不能包含用户名 / 账号名(大小写不敏感)
- 不能包含连续 3 位相同字符(
aaa、111) - 不能包含连续升序 / 降序 3 位(
123、321、abc、cba)
✅ 严格版(管理员账号、VPN、Radius、LDAP、核心业务,推荐)
- 长度 ≥12
- 至少包含 3 种 上面 4 类字符
- 不能包含用户名 / 账号名(大小写不敏感)
- 禁止连续 3 位相同字符(
aaa) - 禁止连续升序 / 降序 3 位(
123/cba) - 禁止常见弱密码黑名单匹配(字典)
- 禁止密码是账号名反转
- 禁止密码包含手机号、生日片段(可选增强)
可选增强项:禁止重复使用历史 N 次密码(如最近 5 次密码不可复用)
三、密码强度评分算法(0~100 分)
用于前端展示弱 / 中 / 强,不替代硬性规则:硬性规则不满足直接拒绝,分数仅做参考。
- 基础分:长度 × 4
- 字符种类加分:
- 2 类:+10
- 3 类:+20
- 4 类:+30
- 额外加分:含特殊字符额外 + 5
- 扣分项:
- 连续 3 相同字符:-15
- 连续 3 顺序字符:-15
- 包含用户名:-20
- 在弱密码黑名单:直接置 0
强度等级映射
- 0~39:弱(禁止)
- 40~69:中(基础业务可放行,管理员账号禁止)
- 70~100:强(推荐)
四、伪代码(可直接转 C++/Python/JS)
// 输入:password(待检测密码), username(账号名), mode="strict" / "basic"
// 输出结构体:
// {
// pass: bool,
// score: int,
// level: string, // weak/medium/strong
// msg_list: array<string> // 不满足原因
// }
Function CheckPasswordComplexity(password, username, mode):
msg_list = empty array
score = 0
// 1. 长度校验
min_len = 8
if mode == "strict":
min_len = 12
if length(password) < min_len:
add msg_list, "密码长度不足,最少要求"+min_len+"位"
// 2. 判断4类字符是否存在
has_upper = RegexMatch(password, "[A-Z]")
has_lower = RegexMatch(password, "[a-z]")
has_digit = RegexMatch(password, "[0-9]")
has_special = RegexMatch(password, "[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]")
type_count = count_true(has_upper, has_lower, has_digit, has_special)
require_type = 2
if mode == "strict":
require_type =3
if type_count < require_type:
add msg_list, "字符种类不足,至少需要"+require_type+"种字符(大写/小写/数字/符号)"
// 3. 检测连续3相同字符
if RegexMatch(password, "(.)\1\1"):
add msg_list, "禁止3个连续相同字符"
// 4. 检测连续升序/降序
if HasSeq3(password):
add msg_list, "禁止3位连续顺序字符(如123、abc)"
// 5. 账号名检测(大小写不敏感)
low_pwd = ToLower(password)
low_user = ToLower(username)
if low_user != "" and low_pwd contains low_user:
add msg_list, "密码不能包含账号名称"
// 6. 弱密码黑名单校验
if IsInWeakDict(low_pwd):
add msg_list, "该密码属于常见弱密码,禁止使用"
// 强度评分计算
score = length(password)*4
if type_count ==2: score +=10
if type_count ==3: score +=20
if type_count ==4: score +=30
if has_special: score +=5
if RegexMatch(password, "(.)\1\1"): score -=15
if HasSeq3(password): score -=15
if low_user != "" and low_pwd contains low_user: score -=20
if IsInWeakDict(low_pwd): score =0
// 分数边界裁剪
score = Clamp(score, 0, 100)
// 等级
if score <40: level="weak"
else if score <70: level="medium"
else: level="strong"
// 是否通过:无错误消息即通过
pass = (length(msg_list)==0)
return {pass, score, level, msg_list}
// 辅助函数:检测连续3位顺序字符 123/321/abc/cba
Function HasSeq3(s):
for i from 0 to len(s)-3:
c1 = s[i], c2=s[i+1], c3=s[i+2]
// 升序 c2=c1+1 && c3=c2+1
if (Ord(c2)==Ord(c1)+1 && Ord(c3)==Ord(c2)+1):
return true
// 降序 c2=c1-1 && c3=c2-1
if (Ord(c2)==Ord(c1)-1 && Ord(c3)==Ord(c2)-1):
return true
return false
// 辅助函数:弱密码字典匹配(读取弱密码列表,大小写不敏感)
Function IsInWeakDict(lower_pwd):
return lower_pwd in WeakPasswordSet
五、弱密码字典建议
来源:常见 top 弱密码集合
123456、password、qwerty、admin123、111111、abc123
生产环境建议加载 10 万 + 弱密码库;可定期更新。
六、边界注意事项
- 前后空格:建议自动 trim,或者直接判定首尾空格非法(看业务)
- Unicode 字符:中文、emoji 等,若业务允许,只计入长度,不计入 4 类字符集,防止绕过规则
- 正则引擎:特殊符号正则记得转义,避免注入
- 不要在前端单独校验!前端仅做提示,后端必须重复完整校验(前端可被绕过)
- 密码不要明文存储,校验时仅接收明文用于复杂度判断,判断完成立刻丢弃明文
七、输出示例
示例 1:密码 Abc12345,基础模式
- 长度 8;大小写 + 数字,3 类;包含连续顺序
abc、123 - 结果:
pass=false,提示:禁止 3 位连续顺序字符
示例 2:密码 K9s@P27q,严格模式
- 长度 8 <12;不通过;提示长度不足
示例 3:密码 Mk7$s92pRz!5,严格模式
- 长度 13;大小写、数字、符号(4 类);无连续重复 / 顺序;不含用户名;不在黑名单
- pass=true,score=88 level=strong