Checking strings for a strong enough password

48,061

I can't take the credit, as I stole this from here

using System.Text;
using System.Text.RegularExpressions;

  public enum PasswordScore
  {
    Blank = 0,
    VeryWeak = 1,
    Weak = 2,
    Medium = 3,
    Strong = 4,
    VeryStrong = 5
  }

  public class PasswordAdvisor
  {
    public static PasswordScore CheckStrength(string password)
    {
      int score = 0;

      if (password.Length < 1)
        return PasswordScore.Blank;
      if (password.Length < 4)
        return PasswordScore.VeryWeak;

      if (password.Length >= 8)
        score++;
      if (password.Length >= 12)
        score++;
      if (Regex.Match(password, @"/\d+/", RegexOptions.ECMAScript).Success)
        score++;
      if (Regex.Match(password, @"/[a-z]/", RegexOptions.ECMAScript).Success &&
        Regex.Match(password, @"/[A-Z]/", RegexOptions.ECMAScript).Success)
        score++;
      if (Regex.Match(password, @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/", RegexOptions.ECMAScript).Success)
        score++;

      return (PasswordScore)score;
    }
  }

Note the use of regex for checking for upper case characters. This appears to be a decent approach, as it checks length, use of upper and lower case characters, numeric digits and special characters.

** Update **

I know the question is now closed, but I can add more explanation for VoidKing to understand some of the concepts.

A PasswordScore is returned from the CheckStrength method, which can be used as the condition for what to do next in your code.

Here's an untested demo of how the above code could be used:

String password = "MyDummy_Password"; // Substitute with the user input string
PasswordScore passwordStrengthScore = PasswordAdvisor.CheckStrength(password);

switch (passwordStrengthScore) {
    case PasswordScore.Blank:
    case PasswordScore.VeryWeak:
    case PasswordScore.Weak:
            // Show an error message to the user
            break;
    case PasswordScore.Medium:
    case PasswordScore.Strong:
    case PasswordScore.VeryStrong:
           // Password deemed strong enough, allow user to be added to database etc
           break;
}

Enums are used in this case as a means of classifying the strength of the password into human-readable groups. Keeps the code clean, and makes it obvious what is going on in the code.

Regarding the use of Regex's, if you're unfamiliar with the concept of them and how and when to use them, I suggest doing some research as these can be useful in many different scenarios for checking for patterns in strings. Perhaps start here.

Share:
48,061

Related videos on Youtube

VoidKing
Author by

VoidKing

I am currently an IT specialist for a municipal organization in the state of Oklahoma, and while I perform all sorts of IT specific tasks, my projects almost always include programming/web development. Since I started (a newb fresh out of college) I have learned a massive amount about programming best practices and functionality. I very much have Stack Overflow to thank for a lot of this. I have come to be an avid believer of Stack Exchange and their original goals (goals I think they are accomplishing very well, I might add). As a programmer, who constantly has to try new things, Stack Overflow has proven an invaluable resource for me. I try, research, try again, delve into old school books, and try again, but when push comes to shove, there are many times when my current level of experience in whatever language, proves inadequate and leaves me scratching my head, so to speak. It seems, that when I am in my darkest hour of coding, Stack Overflow (i.e., the community therein) not only gets me through the problem, but also teaches me how I can handle similar situations in the future, thus always making me a better programmer all around. :) I enjoy programming more than any other IT related task. Guess that's just who I am, but I suppose I am preaching to the choir here.

Updated on July 09, 2022

Comments

  • VoidKing
    VoidKing almost 2 years

    Possible Duplicate:
    Strong password regex
    Need RegEx for password strength?

    I was just wondering what the best way to search a string for certain criteria (password strength to be specific) could be accomplished.

    So far I have a simple:

    if(password.Length <= 7)
        {
            errorMessage = "Your password must be at least 8 characters.";
        }
    

    I would like to be able to check for capital letters, but I am not sure what the method or procedure is. I have tried Googling, searching the website: http://msdn.microsoft.com, and searching the index of my C# book (C# Programming 3E, by Barbara Doyle), but I can't seem to find any.

    I know I could try this...:

    foreach(char c in password)
        {
            if(c!='A' || c!='B' || c!='C' || c!='D' ..... || c!='Z')
            {
                errorMessage = "Your password must contain at least one capital letter";
            }
        }
    

    ...But that would be extremely sloppy, and would have to be doubled to check for at least one lowercase letter. I am sure there is a better way to do this, or at least shorthand for the method I have shown above.

    Also, I may decide to check the password for special characters (seems easier to do in the example above than with upper and lower case letters, so I may just use that for special characters, should I decide to make them necessary). If there is an easy (or proper) way to do that, I would love to have that knowledge, as well.

    Anyway, thank you so much for any help anyone can give.

    • David
      David over 11 years
      This isn't an answer, but be sure you understand xkcd.com/936 and xkcd.com/792 And I also recommend reading codinghorror.com/blog/2010/12/… and searching Jeff's site for other related articles. Then look at Regular Expressions for verifying the appropriate length/complexity.
    • David Hoerster
      David Hoerster over 11 years
      Instead of a series of if...then clauses, you'd probably want to run the password through a regular expression. Take a look at this SO answer. I think it provides the Regular Expression that will help you.
    • VoidKing
      VoidKing over 11 years
      @DarinDimitrov Hey, thanks for that, I didn't see that link, because I didn't know to search for regex (although, I guess it's kind of obvious). My apologies, and thnx for the link!
    • Aerik
      Aerik over 5 years
      I very strongly disagree with the decision to close this question of as a duplicate by referencing only questions asking about regular expressions. The OP did not explicitly ask for a regex answer and some people may not find the use of regex to be the "best" answer since not everyone can easily understand regular expressions.
  • VoidKing
    VoidKing over 11 years
    Dude, you deserve some rep, just for how useful this is overall... Until now, I had no idea how they rated passwords on that scale... Thank you!
  • VoidKing
    VoidKing over 11 years
    How does this Regex work exactly? I'd like to be able to make my own. Am I right in assuming that it checks each character (and succeeding characters if the previous is a match) for matches within the regex string provided? (forgive me if I am not using regex correctly, grammatically speaking)
  • VoidKing
    VoidKing over 11 years
    Well, I was trying this, but I just don't know enough about this procedure. I just started pathing to (or using or whatever its called) external .cs files, and I can do that, but I can't seem to work with any of the data that this class is supposed to supply. It's never enough that I have code, I must also understand it in order to implement it into my applications, and I simply put, do not, here. What is ECMAScript? why enum? what kind of data is returned? (I found out I can't cast it into anything useable). Anyway, thanks for trying to help.
  • Steve Kennaird
    Steve Kennaird over 11 years
    I've updated the answer to help you further. Hope you find it useful.
  • Nikolaj Dam Larsen
    Nikolaj Dam Larsen almost 10 years
    I like it, although I would start the score at 0 to enforce even stronger passwords. As it is now 12345678 would be scored as medium strength, which I really don't agree with. :-)
  • Sumit Gupta
    Sumit Gupta almost 10 years
    The password as Password@123 will produce PasswordScore as 6 which is not defined in enum. So the score must start with 0 to make it more reliable function.
  • Paul Knopf
    Paul Knopf over 9 years
    I had to take out the trailing/leading "/"s to get this to work.
  • user420667
    user420667 almost 8 years
    While this is good, it is essentially saying +1 for any of the following( length > 8, length > 12, has a lowercase alphabetical character, has an uppercase alphabetical character, has a digit, has a special character.) Because most of the logic is in regexes, it would be easily extendable to javascript. The only problem is that it doesn't check common words / consecutives etc. Not to say it's not a good solution, it just needs to be taken with a grain of... salt.
  • Deantwo
    Deantwo about 7 years
    Wouldn't String.IsNullOrEmpty(password)make more sense than password.Length < 1?
  • JPelletier
    JPelletier over 6 years
    @SumitGupta In fact there is a missing enum value, score must start at 1 otherwise password.Length < 4 and password.Length >= 8will both return a value of PasswordScore.VeryWeak. I added value PasswordScore.TooShort = 1 and returned this if password.Length < 4. All other enum values must be incremented by one. I edited the answer with my fixes
  • JPelletier
    JPelletier over 6 years
    I "tried" to edit the answer with my fixes, but it seems that it was rejected :( if you copy/paste the code please read my above comment
  • Garr Godfrey
    Garr Godfrey over 3 years
    I'd add + and =.
  • Garr Godfrey
    Garr Godfrey over 3 years
    @JPelletier I'm not sure >=8 being veryweak is a problem, but there's definitely a problem with passwords length 5,6 and 7 returning "Blank" (if they have no other qualities)