What makes a strong password? This quick and dirty password strength meter is meant to help users learn how to create stronger passwords. Because it's written in Javascript the password is never sent over the network. Feel free to audit the code and recommend some better regular expressions, weightings, or bug fixes by submitting a comment.

NOTE: This was meant as a quick and dirty educational tool. It served my purposes many years ago. If you want to make it better please submit a comment with a patch or some type of improvement. Other than that I'm going to ignore comments like, "I put in XYZ password at it said it was weak, strong, whatever."

Tips for strong passwords:

- Make your password 8 characters or more
- Use mixed case letters (upper and lower case)
- Use more than one number
- Use special characters (!,@,#,$,%,^,&,*,?,_,~)
- Use L33t
- Use a random password generator/password vault like Password Safe or pwsafe
- Use PasswordMaker

Blogs:

## Comments

## Excellent application that was easy to integrate!

https://secure.quty.com/q,d/Register?cmd=user_country&QDD=global Thanks for a great app Steve! -Dick Ervasti

Cofounder / CTO

Quty Global Auction Network

## Thanks

## CSS meter Version

## Thanks

## Java version with minor regex fixes

Jim

## Cool

## new regex for combo

`if (passwd.match(/([a-zA-Z])/) && passwd.match(/([0-9])/)) { // both letters and numbers`

you might have already changed that... or please let me know if that doesn't work. thanks again!

---

zack

zacksmithdesign.com

## Thanks!

## Source code license?

## Re: Source code license

## Another taker

## And another

## download

## From here

## Fixed Regex

// LETTERS

if (passwd.match(/[a-z]/)) // [verified] at least one lower case letter

{

intScore = (intScore+1)

} if (passwd.match(/[A-Z]/)) // [verified] at least one upper case letter

{

intScore = (intScore+5)

} // NUMBERS

if (passwd.match(/\d+/)) // [verified] at least one number

{

intScore = (intScore+5)

} if (passwd.match(/(\d.*\d.*\d)/)) // [verified] at least three numbers

{

intScore = (intScore+5)

} // SPECIAL CHAR

if (passwd.match(/[!,@#$%^&*?_~]/)) // [verified] at least one special character

{

intScore = (intScore+5)

} if (passwd.match(/([!,@#$%^&*?_~].*[!,@#$%^&*?_~])/)) // [verified] at least two special characters

{

intScore = (intScore+5)

} // COMBOS

if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/)) // [verified] both upper and lower case

{

intScore = (intScore+2)

} if (passwd.match(/\d/) && passwd.match(/\D/)) // [verified] both letters and numbers

{

intScore = (intScore+2)

} // [Verified] Upper Letters, Lower Letters, numbers and special characters

if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/) && passwd.match(/\d/) && passwd.match(/[!,@#$%^&*?_~]/))

{

intScore = (intScore+2)

}

## Scriptaculous version

I used this script to create a dynamic version with scriptaculous, click here to see the (nice :-) ) result.

## Weighting

## Erm... I'm talking rubbish.

## This page has some

http://www.lockdown.co.uk/?pg=combi I'll work out some better weighing from this.

## From that analysis...

<head>

<script language="JavaScript1.1">

<!-- Begin

/* ************************************************************

Created: 20060120

Author: Steve Moitozo

Description: This is a quick and dirty password quality meter

written in JavaScript so that the password does

not pass over the network

Revision Author: Dick Ervasti (dick dot ervasti at quty dot com)

Revision Description: Exchanged text based prompts for a graphic thermometer

Revision Author: Matt Culverwell (zebadger@hotmail.com)

Revision Description: Fixed regular expressions

Revision Author: Matt Culverwell (zebadger@hotmail.com)

Revision Description: Added brand new weighting based on figures from http://www.lockdown.co.uk/?pg=combi

************************************************************ */

function testPassword(passwd)

{

var description = new Array();

description[0] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=30 bgcolor=#ff0000></td><td height=4 width=120 bgcolor=tan></td></tr></table></td><td> <b>Weakest</b></td></tr></table>";

description[1] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=60 bgcolor=#990000></td><td height=4 width=90 bgcolor=tan></td></tr></table></td><td> <b>Weak</b></td></tr></table>";

description[2] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=90 bgcolor=#990099></td><td height=4 width=60 bgcolor=tan></td></tr></table></td><td> <b>Improving</b></td></tr></table>";

description[3] = "<table><tr><td><table cellpadding=0 cellspacing=2><tr><td height=4 width=120 bgcolor=#000099></td><td height=4 width=30 bgcolor=tan></td></tr></table></td><td> <b>Strong</b></td></tr></table>";

description[4] = "<table><tr><td><table><tr><td height=4 width=150 bgcolor=#0000ff></td></tr></table></td><td> <b>Strongest</b></td></tr></table>";

description[5] = "<table><tr><td><table><tr><td height=4 width=150 bgcolor=tan></td></tr></table></td><td> <b>Begin Typing</b></td></tr></table>";

var base = 0

var combos = 0

if (passwd.match(/[a-z]/))

{

base = (base+26);

}

if (passwd.match(/[A-Z]/))

{

base = (base+26);

}

if (passwd.match(/\d+/))

{

base = (base+10);

}

if (passwd.match(/[>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/))

{

base = (base+33);

}

combos=Math.pow(base,passwd.length);

if(combos == 1)

{

strVerdict = description[5];

}

else if(combos > 1 && combos < 1000000)

{

strVerdict = description[0];

}

else if (combos >= 1000000 && combos < 1000000000000)

{

strVerdict = description[1];

}

else if (combos >= 1000000000000 && combos < 1000000000000000000)

{

strVerdict = description[2];

}

else if (combos >= 1000000000000000000 && combos < 1000000000000000000000000)

{

strVerdict = description[3];

}

else

{

strVerdict = description[4];

}

document.getElementById("Words").innerHTML= (strVerdict);

}

// End-->

</script>

</head>

<body>

<table><tr valign=top><td><form name="commandForm">

Type password: <input type=password size=30 maxlength=50 name=password onkeyup="testPassword(document.forms.commandForm.password.value);" value="">

<br/><font color="#808080">Minimum 6 Characters</td><td><font size="1"> Password Strength:</font><a id="Words"><table><tr><td><table><tr><td height=4 width=150 bgcolor=tan></td></tr></table></td><td> <b>Begin Typing</b></td></tr></table></a></td></tr></table>

</td></tr></table>

</form>

<pre>

This works by working out how many sets of characters you have used from

<UL>

<LI>Upper (set of 26)</LI>

<LI>Lower (set of 26)</LI>

<LI>Numeric (set of 10)</LI>

<LI>Symbols (set of 33)</LI>

</UL>

It then works out the number of combinations of passwords that could be made based on the sets that you have used and the password length.

Weakest < 1000000

Weak < 1000000000000

Improving < 1000000000000000000

Strong < 1000000000000000000000000

Strongest >=1000000000000000000000000

</pre>

</body>

</html>

## I've written the above code

## a dictionnary would be nice...

## I was gonna look at that

## passwordmeter.js

A rather trivial submission but saves CPU cycles.

if(intScore < 16)

{

strVerdict = "very weak"

}

else if (intScore < 25)

{

strVerdict = "weak"

}

else if (intScore < 35)

{

strVerdict = "mediocre"

}

else if (intScore < 45)

{

strVerdict = "strong"

}

else

{

strVerdict = "stronger"

}

## Flex version

http://www.mattholden.com/dslabs/PasswordEntry.swf (demo)

http://www.mattholden.com/dslabs/PasswordEntry.mxml (code) Thanks!

## great, if not for the bugs still in it!

Submitted by Jaeden on Wed, 2008-06-25 22:22.

Used your scoring system (with some minor modifications) to create a Flex/Flash component, also MIT licensed. Check it out...

http://www.mattholden.com/dslabs/PasswordEntry.swf (demo)

http://www.mattholden.com/dslabs/PasswordEntry.mxml (code)

Even with all the alterations afterwards, one simple problem remains: IE

COPY AND PASTE SCREWS IT UPprobably 50% of the time people will instead of re-typing the password, will copy / paste it. And with your code, when they do, the whole page gets screwed, the status bar goes haywire and jumps slap to the right going off the edge, etc...

great code, just needs tweaked.

## some work on the regex

Hi, found the code while googlin' for a JS password checker - nice one, and useful for my purposes. So, I decided to adopt it for my project, with some minor mods, especially by re-writing the regex.

Ah, one word to the combination changes: I decided not to implement them, because IMHO all these are checked beforehand and don't really add strength.

Well, here's my version. It's written as a JS function, and just returning the strength, since this is what I needed - maybe someone can use it.

checkpwd: function(password) {

/*function to calculate "strength" of a password

* expects password, returns strength

*/

//calculate strength out of length

var strength = 0;

var length = password.length;

if (length > 16) {

strength = 18;

} else {

if (length > 8) {

strength = 12

} else {

if (length > 5) {

strength = 6;

} else {

if (length > 0) {

strength = 3;

} else {

return 0; //no password means no strength, :-)

}

}

}

}

//Now consider the letters

if (password.match(/[a-z]/i)) {

strength += 5; //at least one letter, 5 points

if (password.match(/[a-z][A-Z]|[A-Z][a-z]/)) {

strength += 2; //mixed-case adds 2 points

}

} //no letter, no points

//Now check for numbers

count = password.match(/[0-9]/g);

if (count) {

strength += 5; //at least one number, 5 points

if (count > 2) {

strength += 2; //three or more numbers, 2 extra points;

}

} //no number, no points

//Now check for special characters

count = password.match(/[!,@,#,$,%,^,*,?,_,~,-]/g)

if (count) {

strength += 5; //at least one special characters, 5 points

if (count > 1) {

strenth += 2; //two or more special characters, 2 extra points

}

} //no special characters, no points

return strength;

}

## Different approach to password strength calculation

I could see it in my mind: a kind of frequency spectrum bar-chart of password components pulsing up and down like the graphic VU meter on a DJ's mixing panel. The height of the vertical bars represents the number of lowercase, uppercase, numbers and special characters present in the password as it is typed by an unsuspecting User--a password histogram. If the bars are more or less the same height the password is stronger than if the heights of the bars vary. The more irregular the heights are, the weaker is the password.

Also, as the password length increases, the overall height of the bars increases. Thus, the taller the meter, the stronger, yet, is the password. In my gut I knew there was a way to express this mathematically and after fiddling around with it, I drew the bars on a piece of paper, and that's when I saw it: each bar is a dimension on a crazy 4-dimensional solid. Multiply the dimensions together and you get a volume. The larger the volume, the stronger the password. All that is left is to determine the thresholds for the various degrees of strength.

It's easier to see in 3 dimensions. Picture a hexahedron with rectangular faces. It has a height, a width and a depth. Assign the

uppercasecount to the height, thenumberscount to the width, and thespecial charscount to the depth. If all the counts are equal, then the shape is acube. If, the counts vary, then the shape is composed of rectangles. Say the password is 9 characters long, and it has 3 uppercase, 3 numbers and 3 special chars. The volume is 3*3*3 or 27. Now, suppose the counts are: 7 uppercase, 1 number and 1 special char. The volume becomes a long thin sort of square rod kind of solid with a volume of 7*1*1 or 7 (much less than 27). How about something in the middle: 5 uppercase, 2 numbers and 2 special chars. That's 5*2*2 or 20, which is still less than 27. A cube is always going to have the greatest volume.This also includes a "runs" detector. It's basically a digital hi-pass filter (or edge detector) with rectification (absolute zero applied to each difference). See comment on the detectRuns() method for details (this, almost certainly doesn't work with Unicode.). This, actually, could be used to generate an overall password strength, if the various char ranges were weighted to produce filterable edge intensities.

Here's the listing:

## Great

Very usefull tips