Build a Simple Password Strength Checker
Providing instant feedback is the in-thing right now. Why limit yourself to checking usernames and email addresses? Why not extend this to provide quick visual feedback about the strength of the password the user has input? Today, we’ll take a look at how to create a simple password strength checker using the jQuery library, regular expressions and a simple algorithm.
A Word From the Author
As most security experts will tell you, the user is always the weakest link. The most secure of systems are vulnerable when a user chooses an extremely ill-advised password. With that in mind, the recent trend seems to be providing quick feedback to the user regarding the strength of the password so the user can extend or modify the password to make it more secure.
Today, we are going to use the jQuery library, a bunch of regular expressions and a very simple algorithm to create a basic password strength checker. Interested? Let’s get started right away! Here is a demo of what we are trying to build today:
Design Goals
Our design goals for this specific functionality is relatively small.
- Provide visual feedback to the user regarding the strength of their password.
- The feedback has to be instantaneous. This means no clicking on a button to test the strength.
- The trigger event can be any of the key board events. I’ve chosen keyup since this is the most appropriate for our specific need.
- For the visual feedback, modifying the text alone, while useful, is severely lacking. I’ve chosen to change the background colors as well to draw the user’s attention to this.
- Provide additional quantifiable feedback so the user knows in which departments the password lacks strength and how it can be improved.
Now that we’ve adequately figured out our needs, we can move on to the next stage.
Plan of Action
We’ll now decide on the order of the individual steps that need to be done.
- Hook up the event handler to the keyup event of the input box.
- Let the event handler check the input but delegate everything else to individual helper methods.
- The helper methods should take care of parsing the input and analyzing it, computing the complexity and printing out the results.
- Make sure the event handlers fires off the helper methods only if the length of the input is greater than the expected minimum so as to not waste CPU cycles on invalid entries.
- Return control to the event handler in case anything else needs to be done.
The Algorithm
In in the interest of keeping this write up succinct and approachable, I’ve decided to go with a very basic algorithm. The algorithm analyzes the string, gives bonuses for extra length, presence of numbers, symbols and upper case letters and penalties for letter or number only inputs. We aren’t going to look at matching common patterns or checking the input against a dictionary since this is out of the scope of the article. If interest peaks, I may do an article about this in the future.
First we check the length of the input string. If it’s greater than the minimum length, give it a base score of 50. Else make it 0. Next iterate through each character of the string and check if it is a symbol, number or upper case letter. If so, make a note of it.
Then check how many extra characters the string has, over the recommended minimum and grant a bonus for each character. Also grant a bonus if the string contains a combination of upper case letters, numbers and symbols or all three. Grant a bonus for each’s presence too.
Check if the string only contains either lower case letters or numbers and if so, penalize.
Add up all the numbers and decide the strength of the password accordingly.
That’s the long and short of the algorithm. It’s not going exceedingly suave but it catches a lot of bad passwords. You’ll understand this better once we see it in code.
Core Markup
The HTML markup of the demo page looks like so:
<!DOCTYPE html> <html lang="en-GB"> <head> <title>Simple Password Strength Checker - by Siddharth for NetTuts</title> <link type="text/css" href="css/style.css" rel="stylesheet" /> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/mocha.js"></script> </head> <body> <div id="container"> <h1>Create a simple password strength checker</h1> <h2 class="bolded">by Siddharth for the lovely folks at Net Tuts</h2> <p>Type in your password to get visual feedback regarding the strength of your password.</p> <p>I assure you, I am not stealing your passwords. The form doesn't not submit. You can look through the source if you are suspicious. :)</p> <div class="block"> <input id="inputPassword"/> <div id="complexity" class="default">Enter a random value</div> </div> <div class="block"> <div id="results" class="default">Breakdown of points</div> <div id="details"></div> </div> </div> </body> </html>
Disregard all the usual markup. Do notice the input element with an ID of inputPassword, the div element with an ID of complexity which shows the complexity of the password and div element with an ID of details which shows the breakdown of points.
We’ve also included the jQuery library and our own script file. Extra points if you appreciate the name of our script file.
CSS Styling
body{
font-family: "Lucida Grande", "Verdana", sans-serif;
}
h1{
font-size: 30px;
padding: 0;
margin: 0;
}
h2{
font-size: 18px;
padding: 0;
margin: 0 5px 30px 0;
}
input{
width: 288px;
height: 30px;
margin: 50px 0 0 0;
padding: 3px 5px;
font-size: 22px;
font-family: "Lucida Grande", "Verdana", sans-serif;
}
#container{
width: 820px;
margin-left: auto;
margin-right: auto;
padding: 50px 0 0 0;
}
.block{
width: 300px;
margin: 0 auto 0 auto;
}
#complexity, #results{
width: 300px;
padding: 3px 0;
height: 20px;
color: #000;
font-size: 14px;
text-align: center;
}
#results{
margin: 30px 0 20px 0;
}
.default{background-color: #CCC;}
.weak{background-color: #FF5353;}
.strong{background-color: #FAD054;}
.stronger{background-color: #93C9F4; }
.strongest{background-color: #B6FF6C;}
span.value{
font-weight:bold;
float: right;
}
Just boiler plate CSS for layouts and typography. We do have a bunch of classes at the bottom for each individual strength ratings. We’ll add them to the elements when needed.
JavaScript Implementation
Now that we have a solid framework and some basic styling in place, we can start coding up the required functionality. Do note that we make extensive use of jQuery. Feel free to link to Google’s CDN if necessary.
Variables and Event Handling
Since a lot of number juggling is going to go on, we need a bunch of variables to hold the values. Since is a demo and not production code, I’d decided to declare the variables as global and access them through the helper methods instead of declaring them internally and then passing it to the functions.
var strPassword;
var charPassword;
var complexity = $("#complexity");
var minPasswordLength = 8;
var baseScore = 0, score = 0;
var num = {};
num.Excess = 0;
num.Upper = 0;
num.Numbers = 0;
num.Symbols = 0;
var bonus = {};
bonus.Excess = 3;
bonus.Upper = 4;
bonus.Numbers = 5;
bonus.Symbols = 5;
bonus.Combo = 0;
bonus.FlatLower = 0;
bonus.FlatNumber = 0;
The variable names are pretty standard fare but I’d give a rundown anyway. strPassword holds the input box’s value, charPassword is an array holding each character of the string, complexity holds a reference to the div element. We also define the minimum password length, score and the base score.
We create a quick hash to hold the number of extra characters, upper case characters, numbers and symbols. We do the same for the bonuses. The num hash holds the number of characters while the bonus hash holds the bonus multipliers. You can just create individual variables but I think this looks cleaner.
Don’t forget to hook up the event handler to the event.
$("#inputPassword").bind("keyup", checkVal);
checkVal is the event handler which we’ll create in just a tiny bit.
The Event Handler
function checkVal()
{
if (charPassword.length >= minPasswordLength)
{
baseScore = 50;
analyzeString();
calcComplexity();
}
else
{
baseScore = 0;
}
outputResult();
}
We first check the length of the input string. If it’s greater than or equal to the minimum specified length, we can proceed. We set the base score to 50 and call the helper methods which take care of analyzing the string and computing it’s complexity.
If it’s less than the expected length, we just set the base score to 0.
We then call the outputResult function which takes care of making sense of the computed computations. We’ll see how it works later below.
Analyzing the Input
function analyzeString ()
{
for (i=0; i<charPassword.length;i++)
{
if (charPassword[i].match(/[A-Z]/g)) {num.Upper++;}
if (charPassword[i].match(/[0-9]/g)) {num.Numbers++;}
if (charPassword[i].match(/(.*[!,@,#,$,%,^,&,*,?,_,~])/)) {num.Symbols++;}
}
num.Excess = charPassword.length - minPasswordLength;
if (num.Upper && num.Numbers && num.Symbols)
{
bonus.Combo = 25;
}
else if ((num.Upper && num.Numbers) || (num.Upper && num.Symbols) || (num.Numbers && num.Symbols))
{
bonus.Combo = 15;
}
if (strPassword.match(/^[\sa-z]+$/))
{
bonus.FlatLower = -15;
}
if (strPassword.match(/^[\s0-9]+$/))
{
bonus.FlatNumber = -35;
}
}
This maybe look a bit complicated but I promise you, it’s only because of the regular expressions. Let’s go over the code part by part.
First, we need to figure out the composition of the string in question. As in, we need to figure out whether the string contains upper case letters, numbers of symbols and if so, how many of them are present. With this in mind, we iterate through the character array and check each characters to see its type. The match method lets us match a string against a regular expression. If you are new to regular expression, I suggest you read Vasili’s great article here.
Next, we have determine the difference between the length of the input string and the specified minimum length of the password. This gives us the excess number of characters to play around with.
We then check if the string has upper case, numbers and symbols. If so, grant a bonus. We also check to see whether it has combinations of two of them and grant a smaller bonus if so.
Finally, we check to see whether a string is flat: whether it contains only lower case letters or only numbers. We check this with a regular expression and if so, penalize the password for this practice.
Calculate the Complexity
function calcComplexity()
{
score = baseScore + (num.Excess*bonus.Excess) + (num.Upper*bonus.Upper) + (num.Numbers*bonus.Numbers) +
(num.Symbols*bonus.Symbols) + bonus.Combo + bonus.FlatLower + bonus.FlatNumber;
}
Just a simple addition. We add the base score to the product of the number of excess characters and it’s multiplier. Same for upper case letters, numbers and symbols. We then add a bonus for combinations, if present, and add penalties if the string is flat.
Updating the UI
Now that all the computation is behind us, we can update the UI to reflect the changes. Here are each of the states.
function outputResult()
{
if ($("#inputPassword").val()== "")
{
complexity.html("Enter a random value").addClass("default");
}
else if (charPassword.length < minPasswordLength)
{
complexity.html("At least " + minPasswordLength+ " characters please!").addClass("weak");
}
else if (score<50)
{
complexity.html("Weak!").addClass("weak");
}
else if (score>=50 && score<75)
{
complexity.html("Average!").addClass("strong");
}
else if (score>=75 && score<100)
{
complexity.html("Strong!").addClass("stronger");
}
else if (score>=100)
{
complexity.html("Secure!").addClass("strongest");
}
}
Nothing fancy here but we’ll go through it line by line.
We first check to see whether input is empty. If so, change the result’s text and add a default class to change it’s background color back to it’s original gray.
If it’s less than the minimum specified length, we change the text accordingly and add a weak class so it’s background is red. We do the same if the total score is less than 50 but change the text to weak.
As the score increases, we change the text accordingly and add the necessary classes. Feel free to change the baseline scores for each rating. I just put in unscientific values to get the demo going.
Updating the Detailed Breakdown
With the main result updated, we can look at updating the stats now.
function outputResult()
{
// Previous Code
$("#details").html("Base Score :<span class=\"value\">" + baseScore + "</span>"
+ "<br />Length Bonus :<span class=\"value\">" + (num.Excess*bonus.Excess) + " ["+num.Excess+"x"+bonus.Excess+"]</span> "
+ "<br />Upper case bonus :<span class=\"value\">" + (num.Upper*bonus.Upper) + " ["+num.Upper+"x"+bonus.Upper+"]</span> "
+ "<br />Number Bonus :<span class=\"value\"> " + (num.Numbers*bonus.Numbers) + " ["+num.Numbers+"x"+bonus.Numbers+"]</span>"
+ "<br />Symbol Bonus :<span class=\"value\"> " + (num.Symbols*bonus.Symbols) + " ["+num.Symbols+"x"+bonus.Symbols+"]</span>"
+ "<br />Combination Bonus :<span class=\"value\"> " + bonus.Combo + "</span>"
+ "<br />Lower case only penalty :<span class=\"value\"> " + bonus.FlatLower + "</span>"
+ "<br />Numbers only penalty :<span class=\"value\"> " + bonus.FlatNumber + "</span>"
+ "<br />Total Score:<span class=\"value\"> " + score + "</span>"
}
This part is not as confusing as it looks. Let me explain.
Instead of just updating the individual values for the detailed results, I’ve resorted to just updating the complete HTML value of the container. I know it is going to be sluggish when a number of these boxes add up but accessing each element individually and then updating it’s value for a tiny demo seemed to be rather counter-productive. So run with me here.
This is just like injecting regular HTML into an element except that we’ve placed a couple variables inside to enable the details to be updated instantaneously. Each value gets a value class to make it bold. We also display the number of special characters and it’s multipler so the user can gauge which elements get more weightage.
A few Tweaks
At this point of time, there are 2 bugs which show up.
- If you type in a long password and then erase the text box, the background colors don’t change back.
- In the same scenario, the details of the points break down don’t update as it should.
We’ll tackle them one by one.
For the first bug, the root cause happens to be the fact that we don’t remove all the other classes. This wouldn’t be a problem if the most recently added classes takes precedence over others. Unfortunately, it’s not so. Here is a quick fix.
function outputResult()
{
if ($("#inputPassword").val()== "")
{ complexity.html("Enter a random value").removeClass("weak strong stronger strongest").addClass("default");}
else if (charPassword.length < minPasswordLength)
{complexity.html("At least " + minPasswordLength+ " characters please!").removeClass("strong stronger strongest").addClass("weak");}
else if (score<50)
{complexity.html("Weak!").removeClass("strong stronger strongest").addClass("weak");}
else if (score>=50 && score<75)
{complexity.html("Average!").removeClass("stronger strongest").addClass("strong");}
else if (score>=75 && score<100)
{complexity.html("Strong!").removeClass("strongest").addClass("stronger");}
else if (score>=100)
{complexity.html("Secure!").addClass("strongest");}
// Details updating code
}
You are probably asking why we don’t remove each and every class here. The answer is simple: we take advantage of one of the primary attributes of CSS: cascading. If you note the order of declaration of each class in the CSS file you’ll notice that default occurs the first and strongest comes the last which means if an element has the strongest class it’ll override any modifications made by any class above it. So we’ll have to only remove classes which occur below the relevant class. For example, for an element to have strong, we’ll have to remove the stronger and strongest classes.
The reason the second bug exist is due to the fact that the individuals variables aren’t reset when a new event occurs. They carry over to the next event as well. In order to fix this, we create a quick function which reinitializes all the relevant variables and add it the checkVal event handler so it is called every time the input box’s text is updated.
function init()
{
strPassword= $("#inputPassword").val();
charPassword = strPassword.split("");
num.Excess = 0;
num.Upper = 0;
num.Numbers = 0;
num.Symbols = 0;
bonus.Combo = 0;
bonus.FlatLower = 0;
bonus.FlatNumber = 0;
baseScore = 0;
score =0;
}
function checkVal()
{
init();
// Other code
}
Limitations
If you’ve been playing around with the demo a bit, you’ll notice that Pa$$W0rd$ turns up as a secure password while in fact it’ll be broken pretty soon. This is due to the simplicity of our algorithm here. We don’t check for character replacements. Or common passwords or patterns for that matter. Doing such things would increase the difficulty of this tutorial while reducing its approachability, both of which I didn’t want for this particular write up.
This is intended as a basic password strength checker. If you need to beef it up, you could probably add a couple more regular expressions to check for patterns and character repetition and then tune the results accordingly.
Looking the input up against a dictionary is really out of the scope of this article and would require either a huge dictionary downloaded to the client side or hooking it up to a server side system to do that. Again, I really wanted to avoid both of them this time.
Conclusion
And there you have it: how to add a user friendly functionality, the ability to let the user know the strength of a password he just entered, to your projects. Hopefully you’ve found this tutorial interesting and this has been useful to you. Feel free to reuse this code elsewhere in your projects and chime in here if you are running into difficulties.
Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!
- Follow us on Twitter, or subscribe to the Nettuts+ RSS Feed for the best web development tutorials on the web.



Awesome! Looking forward to doing this one!
Great work, It’s always been the one part of instant form validation I’ve never delved into. Thanks alot for this =)
Happy I could be of help.
Very cool! Works like a charm. I currently use something similar but this is so much simpler.
This is pretty interesting, I never understood the algorithm. Now I surmise I have a better understanding.
Very cool. This effect is very atractive nowadays.
But if you put many many many numbers, is shows “Secure”.
For who are learning, its great!
It’s more of a tutorial on how to create such a checker instead of something you can just bolt on to your existing applications.
Tank’s this is very awesome!
Nice. Will try this out. Thanks Nettuts.
I was just explaining good password techniques to my girlfriend recently, this will definitely help make the point.
Check that link also http://www.baekdal.com/articles/Usability/password-security-usability/
Eight uppercase letter gives strong password…. for example AAAAAAAA
Tank’s this is very awesome!
abc12345 is a strong password? Really?
I specifically mention this in the tut. Since I wanted to keep it simple, I am not checking for patterns or dictionary words. Maybe in a future tut.
Very nice tutorial, my compliments to the chef. My skills are not anywhere near this level of complexity, but this tutorial is definitively an encouragement for me to keep learning.
Thanks a lot Siddharth, as always your tuts are awesome.
Thank you. I’m really glad you liked it.
Very cool & nifty little thing :) I suck at Javascript and math though.
Of course you do…You’re a gopher. =;]
Haha. Thanks for the laughs.
Great tutorial coming at the right time. I had to do this for a client’s work.
Thank you so much!
Thank *you* for reading. :)
very very nice thanks I like it
Very nicely done, thank you Siddharth.
You have my interest in a tutorial for a more advanced algorithm by the way!
Me too! I definitely enjoyed this. What would be some ways to look for patterns? What patterns would you look for?
Off the top of my head, sequential alphabets and numbers would be at the top of the list followed by common password like password, test, 123abc and so on and so forth.
Great tutorial but one thing I would like to say is I hate it when websites say what my password has to be. At least 8 characters is a popular one, my normal password is 7 characters making it really frustrating.
Yeah I hate it too. Specially when the site stipulates that I absolutely need to stick to its rules whilst choosing a password. It’s really aggravating.
Great tutorial!
But the algoritm considers “12345678″ to be a secure password?
Maybe it should check for sequential numbers and give penatly for it?
Great idea! As I noted, I just didn’t want to complicate the algorithm further than it needed to be. Maybe I should cover it in a future tutorial.
When i fill in _ and that x8 its strong :P?
I dunno if it’s just me, but the form looks funny.
http://i38.tinypic.com/1498e8p.png
I get the same thing in Firefox 3.5.4, IE 8, Chrome 3 using Windows XP SP3.
Just wanted to let you know, over all, this is a great tutorial though.
If you copied CSS from here:
float: rightright;
Very nice tut. Looking forward to try it out. Only one thought. Correct me if I am wrong, but should paaword contain whitespace?
If its hashed (which it always should be), it shouldn’t matter
Well I gues you are right about hash, but still usually on websites they allow only a-Z, 0-9 and _,-,.
No whitespace. But still, I understand your point of view.
I like the tutorial, pretty well documented, kudos! One thing I would like is a little more explanation, or perhaps a link to an explanation, of making the code more “production ready” – as you state you’re declaring the variables as global and accessing them through the helper methods instead of declaring them internally and then passing it to the functions.
That would take an article by itself. :)
Very nice, thank you.
thank for code
thanks, but it would be usefull if you could post that in PHP ..
Why? Posting every request to the server in this case can be a waste of time. If you want to implement something a lot more sophisticated like a dictionary look, then it may come in handy.
Look up*
Who plugin you use for show code in your blog
Good tutorial but the script considers “aaaaaaaaaaaaaaaaaaaaaa” to be strong, gives no lower case penalty, gives upper case bonus and a numbers only penalty of -15 ?
It does say strong but I am pretty sure it doesn’t do the other things you mention.
Thanks for reading.
You are sure it doesn’t do the things I mention? Did you even try it?
http://i36.tinypic.com/25k3s7c.jpg
http://i35.tinypic.com/b9ap7b.jpg
Considers “00000000000″ to be strong, number bonus 0, upper case bonus 9, symbol bonus 55, numbers only penalty 0
Actually I did check it.
http://i37.tinypic.com/21a68y.png
It appears to be a rendering issue with your browser which pushes the results one block down which skews the results.
I like this tutorial. It’s awesome
Not really that secure?
In my opinion it is not, just what carries said, nummerical input like “1111111111″ considered as, strong, but it is really easy to crack.
I reiterate, I am not checking for patters or dictionary words since I wanted to keep it simple. Adding those would make it a lot more complicated than it needed to be. Look for a future tutorial on this.
Thanks for reading.
Very nice tutorial Mr.Siddharth..
Thanks…!! :)
Thank you for reading. Glad you liked it. :)
Net tuts, ¿solo acepta comentarios positivos? Me gustaría saber por qué se ha borrado el mío. Es una vergüenza!
¿Solo se aceptan “Great tutorials”?
Teniendo en cuenta el número de comentarios negativos, no creo que eso es cierto.
Very good Tut! I always wanted to do something like this.
Nice Tutorial, very useful. -Thanks!
This is great, look forward to implementing it
Yey, cool beans all round, super easy to implement :D
Thanks for reading. Glad you liked it.
Cool idea. Definitely something to build on.
Just a grammar note… Doesn’t “The form doesn’t not submit” actually mean the form does submit? :-p
Those double negatives will catch you every time.
Yikes! Double negatives are a pet peeve of mine which is pretty ironic. Thank you for pointing it out. In the future I’ll be more careful proofreading my articles.
Thanks for reading. :)
Since you’re just setting the background-color with each class, it would work just the same to remove all the classes with .removeClass() and then add the single class at each level of “security”
I can understand being very verbose by listing each class and working backwards down the latter but it really doesn’t matter and simplifies your code
You are awesome Siddharth, very nice tut. And I’m also using Inplace editing using jquery.
Interesting bits of code, but it errors, sadly, when you have something like FireFox already inputting a value when the document is ready causing an error with charPassword.length in the outputResult() function. Can be fixed with a ran value though. (:
Great tutorial! Just wanted to let you know that I have added this post to thetutorialist.com – hope it helps!
Thanks for the tutorial!
It works great in my form but after I submit with errors, it stops working… I’m just using basic PHP error checking, so the page does reload. Any ideas?
Heh – figured it out. It was just that
outputResult();was in there twice – just above$("#password").bind("keyup", checkVal);and in thecheckVal()function. Needs to be only in the function.Thanks for the tutorial. It’s nicely laid out, but “11111111111111″ is certainly not a secure password :)
Please checkout the Google like password stength meter
http://www.meosys.com/WEB/webdemo.iface
Your tutorial is awesome. It helps me very much. thanks.
Thanks for the tutorial. It would be awesome if you did another one that included a dictionary word lookup!
Very nice. Is there a way to make it so that onsubmit, the form authenticates and also stops the form from being submitted if the password is, say, less than a score of 75? That would help in cases where a system *must* be secure and also user friendly.
Thanks for the demo, article and source, I’m sure the algorithm could be altered for patter sequences, but a great start. I needed the code to check for white space so added this:
else if (!($(“#inputPassword”).val().match(/^([^\s])*$/))){
complexity.html(“No white space”).removeClass(“strong stronger strongest”).addClass(“weak”);
}
Thanks – Found this interesting and useful.
Hello, Nice tutes you have over here.
mine’s off the subject here.
I would like to have a comment place/page like this one
how or where can i get say a template with code ?
much regards,