我正在使用重置密码。我需要在java中使用正则表达式来重置密码,这样它就不能包含以前密码中的4个连续字符。
答案 0 :(得分:4)
我不认为正则表达式是适合此任务的适当工具。
实际上,我看不到任何其他解决方案,然后会尝试找到4个常见字符的子串。
答案 1 :(得分:2)
正则表达式不是解决每个世界问题的方法。如果使用'indexOf'检查将其实现为普通循环,则代码会更简单,更清晰。
修改强>
我假设您计划在某些应用程序中使用它。如果你只是出于好奇而问,那我就不知道了。)
答案 2 :(得分:2)
你必须动态构建它。假设您之前的密码为“tiddlywinks”。这意味着不允许以下内容:
tidd iddl DDLY dlyw lywi ywin 油墨
恰好如此发生它很好并以4个字符边界结束。没有计划那一个。无论如何。像这样浏览您之前的密码:
public Pattern toValidationExpression( String previousPassword ) {
StringBuilder builder = new StringBuilder();
for( int i = 0; i < previousPassword.length()-4; i++ ) {
if( i > 0 ) builder.append( "|" );
builder.append( "(" );
builder.append( previousPassword.substring(i, Math.min( i+4, previousPassword.length() );
builder.append( ")" );
}
return Pattern.compile( builder.toString() );
}
答案 3 :(得分:1)
通过一些合理的限制,这实际上可以通过正则表达式轻松完成。
假设\n
是密码的非法部分(非常合理的限制),那么以下代码将非常可读地进行检查(如果您知道如何阅读正则表达式):
static boolean legalChange(String before, String after) {
String joined = String.format("%s\n%s", before, after);
return !joined.matches(".*(.{4}).*\n.*\\1.*");
}
这是一个测试工具(see also on ideone.com):
String[][] tests = {
{ "abcdef", "ghijklm" }, // true
{ "abcdef", "xbcdeyz" }, // false
{ "abcdef", "fedbcda" }, // true
{ "xyz", "" }, // true
{ "0123456789", "abc123def456ghi" }, // true
{ "0123456789", "abc123456ghi" }, // false
};
for (String[] test : tests) {
System.out.println(legalChange(test[0], test[1]));
}
请注意,此正则表达式仅检查“no common substring of length 4”规则。还必须有其他密码正则表达式规则。
基本上我们将两个字符串组合成一个字符串,由\n
分隔(无论如何,这也是用户名中的非法字符。)
然后,此正则表达式将匹配 ILLEGAL 更改:
before | after i.e. before = .* (.{4}) .*
| after = .* \1 .*
.*(.{4}).*\n.*\1.*
\____/
1
也就是说,我们将(.{4})
中的before
与{1}}匹配并捕获到第1组,然后使用反向引用\1
来查看它是否可以在after
中匹配。我们将.*
放在这两个周围以允许在任何地方发生。正则表达式引擎将对.*
进行所有必要的回溯,以查看此模式是否匹配。
由于该模式与 ILLEGAL 更改匹配,因此我们使用matches
补码运算符boolean
否定!
的结果。
这不是解决问题的最有效方法,但假设密码长度合理,速度不会成为问题。
答案 4 :(得分:0)
因此,假设您使用char []而不是String来存储旧/新密码有点安全。安全专家有更好的工具......加密/哈希/等...用于密码管理。
所以,这里是:
/** * Compare old to new password to a repeating 4char sequence. * -> require passNew to be >= 4char sequence, else return false. * -> require passOld to be >= 4char sequence, else return true. * -> utilize shifting long to handle full 16Bit char range. * -> does not support char beyond 16Bit char range... e.g. codepoint > 2^16. * -> codepoint > 2^16 support could be done with XOR 4 codepoints with 8bit shifts * @return success true if passNew >= 4char sequence, * passOld lessthan 4char sequence or * normal... 4char sequence not found. */ public final boolean validatePassword(char[] passOld, char[] passNew) { if (passNew.length lessthan 4) { return (false); } else if (passOld lessthan 4) { return (true); } long patOld = ((passOld[0] & 0x0ffL) leftshift 32) | ((passOld[1] & 0x0ffL) leftshift 16) | (passOld[2] & 0x0ffL); long patNewOrig = ((passNew[0] & 0x0ffL) leftshift 32) | ((passNew[1] & 0x0ffL) leftshift 16) | (passNew[2] & 0x0ffL); long patNew; int offOld = 2, lenOld = passOld.length int offNew = 2, lenNew = passNew.length; while (++offOld lessthan lenOld) { patOld = (patOld leftshift 16) | (passOld[offOld] & 0x0ffL); patNew = patNewOrig; offNew = 2; while (++offNew lessthan lenNew) { patNew = (patNew leftshift 16) | (passNew[offNew] & 0x0ffL); if (patOld == patNew) { return (false); } } } return (true); }