这个问题是上面那个问题的后续问题:
为什么char[]比String更适合作为密码?
这个问题很好地理解了为什么使用char[]而不是String;但是,它没有解释如何以安全的方式对char[]执行密码验证。这就是我想知道的。
简单地说,我需要检查密码是否满足以下要求:
- 包含至少一个大写字母
- 包含至少一个小写字母
- 包含至少一个数字
- 包含至少一个符号
- 至少为n个字符,但不超过m
现在我明白了如何使用正则表达式来执行验证…下面的答案告诉我们如何做到这一点:
- 密码验证的Regexp Java
- 密码必须包含1个大写字母,1个特殊字符,1个字母数字字符
据我所知,正则表达式检查涉及到处理字符串。使用它们似乎不安全,因为字符串是不可变的,因此不能在使用它们后立即清除它们。另一方面,char[]可以被清除。
那么,我如何对存储在char[]而不是字符串中的密码执行验证呢?
我可以遍历每个字符,但是我必须创建我想要测试的每个集合。理想情况下,能够利用正则表达式是很有用的。
在Java中,我可以通过以下方法进行正则表达式检查。
String.matches(String regex)
或
Pattern pattern = Pattern.compile(String regex);
pattern.matcher(CharSequence testString).matches();
如您所见,这两种方法都不支持直接使用char[]。
我会尽量避免使用复杂的正则表达式,我建议使用-
boolean validatePassword(char[] password, int n, int m) {
if (password == null || password.length < n || password.length > m) {
return false;
}
boolean upper = false;
boolean lower = false;
boolean digit = false;
boolean symbol = false;
for (char ch : password) {
if (Character.isUpperCase(ch)) {
upper = true;
} else if (Character.isLowerCase(ch)) {
lower = true;
} else if (Character.isDigit(ch)) {
digit = true;
} else { // or some symbol test.
symbol = true;
}
// This short-circuits the rest of the loop when all criteria are true.
if (upper && lower && digit && symbol) {
return true;
}
}
return upper && lower && digit && symbol;
}
只需遍历char[]
进行基本的密码接受验证
可以使用CharBuffer.wrap(char[])
作为CharSequence
访问字符数组
Pattern.matches(regex, CharBuffer.wrap(myCharArray))
Java的regex实现不需要String
对象-您期望传递CharSequence
。如果您不想从char[]
数组创建String
,那么您可以在自己的CharSequence
接口实现中包装一个数组。