Java using regular expressions

I work with password reset. I need a way in java using regular expressions for the reset password, so it cannot contain 4 consecutive characters from the previous password.

+4
source share
5 answers

I do not think regular expression is a suitable tool for this task.

In fact, I do not see another solution, and then a loop that will try to find a substring of 4 common characters.

+4
source

Regular expressions are not a solution to any global problem. You would be much simpler and more understandable if you implemented this as a regular loop with indexOf checking.

change
I assume that you plan to use it in some applications. If you ask only out of curiosity, then I don’t know :)

+2
source

You will need to build it dynamically. Say you have the previous password "tiddlywinks". This means that the following are not allowed:

Tidd iddl DDLY dlyw lywi ywin ink

It just so happens that it’s good and ends on the border with 4 characters. Did not plan this. Anyway. Go through your previous password as follows:

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() ); } 
+2
source

With some reasonable limitations, this can be done quite easily with regular expressions.

Assuming that \n is an illegal part of the password (VERY reasonable restriction), the following code will make the check readable enough (if you know how to read the regular expression):

 static boolean legalChange(String before, String after) { String joined = String.format("%s\n%s", before, after); return !joined.matches(".*(.{4}).*\n.*\\1.*"); } 

Here's the test harness ( see also at 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])); } 

Note that this regular expression only checks the rule "there is no common substring of length 4". Additional regex rules should also be in place.


How it works

Essentially, we concatenate two lines into one, separated by the \n character (which is in any case an illegal character that has names in usernames).

This regular expression will match the ILLEGAL change:

  before | after ie before = .* (.{4}) .* | after = .* \1 .* .*(.{4}).*\n.*\1.* \____/ 1 

That is, we map and remove (.{4}) from before to group 1 and use the backlink \1 to see if it can be matched in after . We put .* Around the two so that the origin takes place anywhere. The regex engine will do all the necessary countdowns on .* To see if this pattern can fit.

Since this pattern corresponds to an unalloyed change, we deny the result of matches using the addition operator boolean ! .

This is not the most effective solution to the problem, but assuming the passwords are of a reasonable length, speed will not be a problem.

References

+1
source

So let's say you use char [] instead of String to store old / new passwords as somewhat secure. Security experts have the best tools ... encryption / hashing / etc ... for password management.

So, like this:

  / **
  * 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 16 Bit char range ... eg 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);
 } 
0
source

All Articles