Previously, in Part 1 of How to Make a Password Strength Meter Like Google I went over the basics on how to get a password strength meter up and running on your site. I got a lot of feedback on this article, mostly commenting on needing a better algorithm to determine if a password is secure or not. The algorithm I implemented in part 1 was mostly just for show. I did not further build out the algorithm because I wanted to leave it up the end user to determine what they considered a secure password or not. Furthermore, I did not want to make a scenario where a flaw in my code would be present in any sites out there that implement this.
After further research in the area of secure passwords, I am further building out the original code base to better determine a secure password from an insecure password. Here are the parameters used for measuring a secure password in version 2.0:
Password Length:
5 Points: Less than 4 characters
10 Points: 5 to 7 characters
25 Points: 8 or more
Letters:
0 Points: No letters
10 Points: Letters are all lower case
20 Points: Letters are upper case and lower case
Numbers:
0 Points: No numbers
10 Points: 1 number
20 Points: 3 or more numbers
Characters:
0 Points: No characters
10 Points: 1 character
25 Points: More than 1 character
Bonus:
2 Points: Letters and numbers
3 Points: Letters, numbers, and characters
5 Points: Mixed case letters, numbers, and characters
Password strength is measure by the percent of the above:
>= 90: Very Secure
>= 80: Secure
>= 70: Very Strong
>= 60: Strong
>= 50: Average
>= 25: Weak
>= 0: Very Weak
Implementation of the code should be the same as version 1.0. The next version will have the ability to blacklist common dictionary words. Hope this works out better than version 1.0.
Code: Version 2.0

Now we’re talking! Good job.
Interesting article. Just a suggestion though:
I’d be inclined to use a regex to do the character counts; not sure if it will make a real difference, but it would be faster, in worst case, than the for loop in countContain().
Something like:
var nUpperCount = strPassword.replace(/[^A-Z]/g, ”).length;
var nLowerCount = strPassword.replace(/[^a-z]/g, ”).length;
var nLowerUpperCount = nUpperCount + nLowerCount;
var nNumberCount = strPassword.replace(/[^0-9]/g, ”).length;
var nCharacterCount = strPassword.replace(/[^!@#$%^&*?_~]/g, ”).length;
Good call… I can implement that here. My only concern is for those that might not have a good regex knowledge and want to make changes to the character strings and stuff. But good contribution!
Much, much better!
I’d change the colours of your comments though – the name/times are barely legible.
Two ifs that I felt were missing from the code in version 2.0 just for the looks and not any functionality. Saying that the empty field has a score of 5 and is weak just looks off;)
if(strPassword.length == 0){
nScore = 0;
} else if… in “checkPassword”
and
if(nScore == 0){
ctrlText.innerHTML = “”;
} in “runPassword”
To be more accurate
FUNCTIOn checkPassword()
line 96
replace
if (nNumberCount == 1)
by
if (nNumberCount >= 1)
Before one number had 10points but 2 had 0
Do the change and 1 or two 2 number will have 10 points
I forgot to say thank you to the author .. that is a nice little feature
I think the score should be proportional to the password length, e.g.
// Password length
if (strPassword.length 4 && strPassword.length 7)
{
nScore += (strPassword.length * 3) + 1;
}
This gives similar scores to the original but with the advantage that the score increases as you add characters, and increases by proportionally more once you get to > 8 characters
Sorry my algorithm got chopped in my previous submission, I meant to say:
if (strPassword.length 4 && strPassword.length 7) {
nScore += (strPassword.length * 3) + 1;
}
Well my algorithm got chopped again – I apologise and leave it as an exercise for the reader! Maybe Safari Beta 3.0 is playing up?
There’s a minor bug on line 167 of the version I downloaded:
vstrColor = “#7ff67c”;
should probably read
var strColor = “#7ff67c”;
so the colour for “secure” changes properly.
Otherwise, nice job
This is better
The previous one was pretty weak.
Perhaps add a common passwords check in too.
Use 20 or so of the most common.
password
changeme
letmein
god
aaaaaaa
12345
abcdef
And so on
What’s the license for this code? I found http://www.geekwisdom.com/dyn/passwdmeter to be under a MIT license and no license for http://www.intelligent-web.co.uk.
Do what you want with the code, (commercial / non-commercial) a mention and link would be appreciated but not required.
Much better! Really well done!
I’m trying to modify the code so it checks the password that is input, cross-references the algorithm’s complexity requirements, and returns “Suggestions” for the password to make it better.
eg: “Please add (1) more character”, “Please use upper case and lower case letters”, “Please use at least (1) number”.
I have it partially working, but the Score and % keep disappearing.
Would anyone like to work on this to make this password strength meter even better than it is now?
Haven’t had the time to go through the script, but wanted to find out if it’s performing input validation checking to ensure XSS attacks are not possible using the password field? Thanks – this is coming along quite nicely.
Modified code 2.0 ! Check it out:
———————
var m_strUpperCase = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
var m_strLowerCase = “abcdefghijklmnopqrstuvwxyz”;
var m_strNumber = “0123456789″;
// Runs password through check and then updates GUI
function runPassword(strPassword, strFieldID)
{
// Check password
var nScore = 0;
nScore += countDifferent(strPassword)/strPassword.length*100*(strPassword.length/10);
var nUpperCount = checkContain(strPassword, m_strUpperCase);
var nLowerCount = checkContain(strPassword, m_strLowerCase);
var nNumberCount = checkContain(strPassword, m_strNumber);
var hinweis=0;
// nur Zahlen
if (nUpperCount == 0 && nLowerCount == 0 && nNumberCount != 0) {
nScore = nScore * 0.4;
hinweis=2;
} else if (nUpperCount != 0 && nLowerCount == 0 && nNumberCount == 0) {
nScore = nScore * 0.7;
hinweis=1;
} else if (nUpperCount == 0 && nLowerCount != 0 && nNumberCount == 0) {
nScore = nScore * 0.7;
hinweis=1;
} else if (nUpperCount != 0 && nLowerCount == 0 && nNumberCount != 0) {
nScore = nScore * 0.9;
} else if (nUpperCount == 0 && nLowerCount != 0 && nNumberCount != 0) {
nScore = nScore * 0.9;
}
var shuffling=getShuffling(strPassword);
if ( shuffling = 100)
{
var strText = “very secure”;
var strColor = “#0ca908″;
}
else if (nScore >= 80)
{
var strText = “secure”;
var strColor = “#0ca908″;
}
// — Average
else if (nScore >= 50)
{
var strText = “good”;
var strColor = “#5a74e3″;
}
// — Weak
else
{
var strText = “bad”
if ( strPassword.length ” + strText + “”;
}
function countDifferent(strPassword)
{
var nCount = new Object();
for (i = 0; i 0 ) {
if ( Math.abs(lastcode-charcode) > 1 ) {
shuffling++;
}
}
lastcode=charcode;
}
return shuffling;
}
function checkContain(strPassword, strCheck)
{
for (i = 0; i -1)
{
return 1;
}
}
return 0;
}