[英]Java using regular expressions
我正在使用重置密碼。 我需要在java中使用正則表達式來重置密碼,這樣它就不能包含前一個密碼中的4個連續字符。
我不認為正則表達式是這項任務的適當工具。
實際上,我看不到任何其他解決方案然后一個循環,它將嘗試找到4個常見字符的子串。
正則表達式不是解決每個世界問題的方法。 如果使用'indexOf'檢查將其實現為普通循環,則代碼會更簡單,更清晰。
編輯
我假設您計划在某些應用程序中使用它。 如果你只是出於好奇而問,那我不知道:)
你必須動態地構建它。 假設您之前的密碼為“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() );
}
有了一些合理的限制,事實上這可以通過正則表達式輕松完成。
假設\\n
是密碼的非法部分(非常合理的限制),那么下面的代碼將非常可讀地進行檢查(如果您知道如何閱讀正則表達式):
static boolean legalChange(String before, String after) {
String joined = String.format("%s\n%s", before, after);
return !joined.matches(".*(.{4}).*\n.*\\1.*");
}
這是一個測試工具( 另見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]));
}
請注意,此正則表達式僅檢查“長度為4的常見子字符串”規則。 其他密碼正則表達式規則也必須到位。
基本上我們將兩個字符串組合成一個字符串,由\\n
分隔(無論如何,這仍然是用戶名中的非法字符)。
這個正則表達式將匹配ILLEGAL更改:
before | after i.e. before = .* (.{4}) .*
| after = .* \1 .*
.*(.{4}).*\n.*\1.*
\____/
1
也就是說,我們從before
匹配並捕獲(.{4})
到組1,並使用反向引用\\1
來查看它是否可以在after
匹配。 我們在這兩個周圍加上.*
以允許在任何地方發生。 正則表達式引擎將對.*
進行所有必要的回溯,以查看此模式是否匹配。
由於該模式與ILLEGAL更改匹配,因此我們否定與boolean
補碼運算符matches
的結果!
。
這不是解決問題的最有效方法,但假設密碼長度合理,速度不會成為問題。
所以,讓我們假設你正在使用的char [],而不是字符串存儲舊/新密碼是偏於安全。 安全專家有更好的工具......加密/散列/等...用於密碼管理。
所以,這里是:
/** * 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); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.