Checking strings for a strong enough password
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.
Related videos on Youtube
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, 2022Comments
-
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 over 11 yearsThis 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 over 11 yearsInstead 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 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 over 5 yearsI 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 over 11 yearsDude, 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 over 11 yearsHow 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 over 11 yearsWell, 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 over 11 yearsI've updated the answer to help you further. Hope you find it useful.
-
Nikolaj Dam Larsen almost 10 yearsI 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 almost 10 yearsThe password as
Password@123
will producePasswordScore
as6
which is not defined inenum
. So the score must start with 0 to make it more reliable function. -
Paul Knopf over 9 yearsI had to take out the trailing/leading "/"s to get this to work.
-
user420667 almost 8 yearsWhile 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 about 7 yearsWouldn't
String.IsNullOrEmpty(password)
make more sense thanpassword.Length < 1
? -
JPelletier over 6 years@SumitGupta In fact there is a missing
enum
value, score must start at1
otherwisepassword.Length < 4
andpassword.Length >= 8
will both return a value ofPasswordScore.VeryWeak
. I added valuePasswordScore.TooShort = 1
and returned this ifpassword.Length < 4
. All otherenum
values must be incremented by one. I edited the answer with my fixes -
JPelletier over 6 yearsI "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 over 3 yearsI'd add + and =.
-
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)