Reputation:
Here is the .NET Regular Expression that I am using to create a strong password (which is not correct for my project password requirements):
(?=^.{15,25}$)(\d{2,}[a-z]{2,}[A-Z]{2,}[!@#$%&+~?]{2,})
Password requirements:
! @ # $ % & + ~ ?
They are not required to be beside one another & in the specific order as the Regular Expression that I pasted requires.
The above Regular Expression requires a password like this: 12abCD!@QWertyP
It REQUIRES them in the specific order in the RE... which is not what I want!
This should pass a correctly formatted RE with the specifications listed above: Qq1W!w2Ee#3Rr4@Tt5
How can I remove the necessity for them to be beside one another and in order?? Obviously the password should be random if the person so chooses.
Upvotes: 3
Views: 4711
Reputation: 2824
^((?=(.*\d){2,})(?=(.*[a-z]){2,})(?=(.*[A-Z]){2,})(?=(.*[!@#$%&+~?]){2,})).{15,25}$
I know this is a year old, but from the few responses, I gathered that this would work.
The top answer is correct except, it just needs a * preceding the pattern.
Upvotes: 0
Reputation:
I think it could be as follow too:
^(?=(.\d){2,})(?=(.[a-z]){2,})(?=(.[A-Z]){2,})(?=(.[!@#$%&+~?]){2,})).{15,25}$
Upvotes: 0
Reputation: 617
^(?=.*\d.*\d)(?=.*[a-z].*[a-z])(?=.*[A-Z].*[A-Z])(?=.*[!@#$%&+~?].*[!@#$%&+~?]).{15,25}$
This regex will do what you want. It will be making up to 5 passes through your password string, but considering what you are doing with it, I don't expect that to be a problem.
Edited to fix a typo that ruined the regex.
Upvotes: 1
Reputation: 75625
This will be much more readable and maintainable in classic code:
The pseudo-code would be:
int count_alpha = 0, count_digit = 0, count_symbol = 0, ...
for each ch in password:
if is_alpha(ch):
count_alpha += 1
elif is_digit(ch):
count_digit += 1
...
if (count_alpha < 2) or (count_digit < 2) or ...
rejection_message()
...
It might be that you're implementing the requirements rather than in a position to influence them, but I'd generally recommend estimating the entrophy and using existing code to do that.
Upvotes: 3
Reputation: 155925
To require one of each character type, you can use this:
(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&+~?])^.{15,25}$
I'm not quite sure how to translate that to require two of each character type, though.
Basically, the ?=
matches a suffix to .*
(i.e. anything), but doesn't capture anything, so you can check that all of the conditions are met specifying order.
Upvotes: 0
Reputation: 340191
As far as I know, you cannot do that reasonably, meaning you'd have to list all possible order combinations in the regex, which would add up to 24 combinations.
I would do 4 separate checks:
\d{2,}
[a-z]{2,}
[A-Z]{2,}
[!@#$%&+~?]{2,}
Related question: Variable order regex syntax
As an aside, your rules look too cumbersome to me I would reconsider them, for example, to have 3 chars of two of etters, digits or symbols.
Upvotes: 2
Reputation: 12815
I think you're looking for more than what a regex was designed to do.
Consider a C#/VB method like this:
bool IsStrongPassword( String password )
{
int upperCount = 0;
int lowerCount = 0;
int digitCount = 0;
int symbolCount = 0;
for ( int i = 0; i < password.Length; i++ )
{
if ( Char.IsUpper( password[ i ] ) )
upperCount++;
else if ( Char.IsLetter( password[ i ] ) )
lowerCount++;
else if ( Char.IsDigit( password[ i ] ) )
digitCount++;
else if ( Char.IsSymbol( password[ i ] ) )
symbolCount++;
}
return password.Length >= 15 && upperCount >= 2 && lowerCount >= 2 && digitCount >= 2 && symbolCount >= 2;
}
Upvotes: 10