user180706
user180706

Reputation:

.NET Regular Expression to create STRONG password

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:

  1. Minimum 15 Character (up to 25)
  2. Two Numbers
  3. Two Uppercase Letters
  4. Two Lowercase Letters
  5. Two Special Characters ! @ # $ % & + ~ ?

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

Answers (7)

CrazyEnigma
CrazyEnigma

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

Owen
Owen

Reputation:

I think it could be as follow too:

^(?=(.\d){2,})(?=(.[a-z]){2,})(?=(.[A-Z]){2,})(?=(.[!@#$%&+~?]){2,})).{15,25}$

Upvotes: 0

Paul Williams
Paul Williams

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

Will
Will

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

bdukes
bdukes

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

Vinko Vrsalovic
Vinko Vrsalovic

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

Bob Kaufman
Bob Kaufman

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

Related Questions