.NET Regular Expression to create STRONG password

2020-03-26 03:53发布

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.

标签: .net regex
7条回答
▲ chillily
2楼-- · 2020-03-26 03:53

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;
}
查看更多
3楼-- · 2020-03-26 03:59
^((?=(.*\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.

查看更多
Ridiculous、
4楼-- · 2020-03-26 04:01

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.

查看更多
Fickle 薄情
5楼-- · 2020-03-26 04:01

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.

查看更多
趁早两清
6楼-- · 2020-03-26 04:05
^(?=.*\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.

查看更多
等我变得足够好
7楼-- · 2020-03-26 04:10

I think it could be as follow too:

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

查看更多
登录 后发表回答