mrblah
mrblah

Reputation: 103497

Creating a regex to check for a strong password

Say I have a regex that checks for alphanumeric.

I now want to create another regex that checks for at least 1 number in the password. And I want to check if it has at least 1 non-alphanumeric character (somethign other than a letter or number).

Should I just call each one seperatley, and if one fails return false or is there a way to combine them into 1 call?

Upvotes: 2

Views: 6455

Answers (7)

Bart Vanseer
Bart Vanseer

Reputation: 548

Regex is not the fastest way.

Give this a try:

string Password = "Pass12!";

bool ValidPassword = Password.Any(char.IsDigit)
    && !Password.All(char.IsLetterOrDigit)
    && Password.Length >= 6;

Instead of:

string Password = "Pass12!";

bool ValidPassword = Regex.IsMatch(Password, @"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$");

I you iterate through it 1 million times it will take the first 157ms and the second 1251ms.

And the most important thing the others said already: much better to maintain.

Upvotes: 0

Philippe Leybaert
Philippe Leybaert

Reputation: 171764

I think this is what you're looking for:

^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$

(will match a password with a minimum length of 6, with at least one digit and one non-alphanumerical character)

In code:

public bool PasswordOk(string pwd) 
{
    return Regex.IsMatch(pwd,@"^.{6,}(?<=\d.*)(?<=[^a-zA-Z0-9].*)$");
}

Upvotes: 2

Draemon
Draemon

Reputation: 34711

Depends on exactly what criteria you're using, but it would probably be better to do a single pass through the string and set a number of flags based on what you've seen:

  • hasDigit
  • hasAlpha
  • hasSymbol
  • etc

Then use these at the end to decide if the password is complex enough.

Even Better:

As lexu suggests, using counts instead of flags would allow greater flexibility.

Upvotes: 3

Don Johe
Don Johe

Reputation: 1019

IMHO, it's a question of style whether to make one or two statements from it.

Why not check for it in any of the two orders that they may appear. (As regular expressions go, we don't have something like a counter for braces or parantheses, thus we have to honor the possible ordering of things.

That one might work for perl:

(\d.*[^[:alnum:]])|([^[:alnum:]].*\d)

Might be easier to read to make two statements from it, especially because then every semantical condition is only occurring once.

Upvotes: 1

dfa
dfa

Reputation: 116314

I would compose small methods using &&:

internal bool HasDigit(string password) { .. }
internal bool HasNonAlpha(string password) { .. }

bool IsStrong(string password) {  
   return HasDigit(password) && HasNonAlpha(password);
}   

Upvotes: 3

Andrea Ambu
Andrea Ambu

Reputation: 39516

You should use two calls. For a bit more advanced testing you can use The password meter. It is freely available for distribution under GPL.

Upvotes: 1

James
James

Reputation: 82096

You add an | (or) operator into the regex e.g.

[0-9]|[A-Z]

Upvotes: 0

Related Questions