在Java开发中,密码强度校验是非常常见的需求,核心目标就是判断输入的字符串密码中是否包含字母、数字和特殊字符,以及各类型字符的占比是否符合预设的强度规则。实现这类校验可以从基础字符遍历和正则表达式两个方向入手,适配不同的业务场景。

基础字符遍历实现方式
这种方式通过遍历字符串的每个字符,逐个判断字符所属的类别,最后统计各类型字符的存在情况。首先需要定义好各类字符的范围:字母包括大小写英文字母,数字为0-9,特殊字符可以根据业务需求自定义范围,比如常见的标点、符号等。
实现步骤
- 初始化四个布尔变量,分别标记是否包含小写字母、大写字母、数字、特殊字符
- 遍历字符串的每个字符,通过
Character类的方法判断字符类型 - 根据判断结果更新对应的标记变量
- 最后根据标记变量的状态判断密码强度
代码示例
public class PasswordStrengthChecker {
// 定义特殊字符的范围,这里包含常见标点
private static final String SPECIAL_CHARS = "!@#$%^&*()_+-=[]{}|;':\",./<>?";
public static PasswordStrength checkStrength(String password) {
if (password == null || password.isEmpty()) {
return PasswordStrength.EMPTY;
}
boolean hasLower = false;
boolean hasUpper = false;
boolean hasDigit = false;
boolean hasSpecial = false;
for (char c : password.toCharArray()) {
if (Character.isLowerCase(c)) {
hasLower = true;
} else if (Character.isUpperCase(c)) {
hasUpper = true;
} else if (Character.isDigit(c)) {
hasDigit = true;
} else if (SPECIAL_CHARS.indexOf(c) != -1) {
hasSpecial = true;
}
}
// 根据包含的字符类型判断强度,这里定义简单的规则
int typeCount = 0;
if (hasLower || hasUpper) typeCount++;
if (hasDigit) typeCount++;
if (hasSpecial) typeCount++;
if (typeCount == 3) {
return PasswordStrength.STRONG;
} else if (typeCount == 2) {
return PasswordStrength.MEDIUM;
} else if (typeCount == 1) {
return PasswordStrength.WEAK;
} else {
return PasswordStrength.INVALID;
}
}
// 密码强度枚举
public enum PasswordStrength {
EMPTY, // 空密码
INVALID, // 不包含任何有效字符类型
WEAK, // 仅包含1种字符类型
MEDIUM, // 包含2种字符类型
STRONG // 包含3种及以上字符类型
}
public static void main(String[] args) {
String testPwd1 = "abc123!";
String testPwd2 = "ABCdef";
String testPwd3 = "123456";
System.out.println(testPwd1 + " 强度:" + checkStrength(testPwd1));
System.out.println(testPwd2 + " 强度:" + checkStrength(testPwd2));
System.out.println(testPwd3 + " 强度:" + checkStrength(testPwd3));
}
}正则表达式实现方式
正则表达式可以更简洁地实现字符类型的检测,通过预定义的正则规则匹配字符串中是否包含对应类型的字符,不需要手动遍历每个字符,代码更简洁。
常用正则规则
- 检测是否包含小写字母:
.*[a-z].* - 检测是否包含大写字母:
.*[A-Z].* - 检测是否包含数字:
.*\\d.* - 检测是否包含特殊字符:
.*[!@#$%^&*()_+\\-=\\[\\]{}|;':\",./<>?].*
代码示例
import java.util.regex.Pattern;
public class PasswordRegexChecker {
// 小写字母正则
private static final Pattern LOWER_PATTERN = Pattern.compile(".*[a-z].*");
// 大写字母正则
private static final Pattern UPPER_PATTERN = Pattern.compile(".*[A-Z].*");
// 数字正则
private static final Pattern DIGIT_PATTERN = Pattern.compile(".*\\d.*");
// 特殊字符正则,注意转义特殊符号
private static final Pattern SPECIAL_PATTERN = Pattern.compile(".*[!@#$%^&*()_+\\-=\\[\\]{}|;':\",./<>?].*");
public static boolean hasLetter(String password) {
return LOWER_PATTERN.matcher(password).matches() || UPPER_PATTERN.matcher(password).matches();
}
public static boolean hasDigit(String password) {
return DIGIT_PATTERN.matcher(password).matches();
}
public static boolean hasSpecialChar(String password) {
return SPECIAL_PATTERN.matcher(password).matches();
}
public static void main(String[] args) {
String password = "Test123!";
System.out.println("是否包含字母:" + hasLetter(password));
System.out.println("是否包含数字:" + hasDigit(password));
System.out.println("是否包含特殊字符:" + hasSpecialChar(password));
}
}注意事项
- 特殊字符的范围需要和产品的密码规则保持一致,避免遗漏或多余包含不需要的字符
- 如果密码支持中文等非ASCII字符,需要额外考虑字符编码的问题,避免判断错误
- 正则表达式中如果有特殊符号,需要做好转义,否则会导致正则匹配逻辑错误
- 校验逻辑建议和业务规则解耦,方便后续调整强度规则时不需要修改核心判断代码