簡體   English   中英

Java使用正則表達式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM