Skip to content

Instantly share code, notes, and snippets.

@ta2edchimp
Created May 8, 2010 15:41
Show Gist options
  • Select an option

  • Save ta2edchimp/394613 to your computer and use it in GitHub Desktop.

Select an option

Save ta2edchimp/394613 to your computer and use it in GitHub Desktop.
//
// PwdMeter - a simple password strength test
//
// (c) 2009, 2010 Andreas "ta2edchimp" Windt <kontakt@andreaswindt.de> twitter.com/ta2edchimp
// Free to use and modify without limitations. Drop me a line when you use it in a project ;)
//
//
// USAGE:
//
// Requires Prototype JavaScript framework to operate!
//
// new PwdMeter( pwdinput [, options] )
// initiates the observation of input element 'element' (should be of type "password"),
// using the following 'options' (when specified):
// - exclude: a string or regular expression of elements to be excluded from the
// typed password (use carefully)
// - onChange: callback function to be triggered whenever the typed password changes
// invoked with the following two parameters:
// - pwdinput: reference to the observed input element
// - strength: numeric value of the password's calculated strength
// (between 0.0 (very weak) and 1.0 (very strong))
//
// PwdMeter.getStrength( pwd ) -> strength
// static function to calculate and return the strength of password string 'pwd'
//
//
// EXAMPLE (requires scriptaculous):
//
// set up the password's html element:
// <input type="password" id="testpwd">
//
// initially set the password element's background color to red:
// new Effect.Morph("testpwd", { style: "background:rgb(255,128,128);", duration: 0.8 });
//
// react with colored background change according to the typed password's strength:
// new PwdMeter("testpwd", { onChange: function(pwdinput, strength) {
// var red = 128 + Math.floor(128 * (1 - strength)),
// green = 128 + Math.floor(128 * strength);
// new Effect.Morph(pwdinput, { style: ("background:rgb(" + red + "," + green + ",128);"), duration: 0.8 });
// } });
//
if (typeof(Prototype) == "undefined") throw "PwdMeter :: Prototype JavaScript framework required!";
var PwdMeter = Class.create({
initialize: function( pwdinput, options ) {
// initialize required objects
this.pwdinput = $(pwdinput);
if (!this.pwdinput)
throw("PwdMeter :: The specified DOM element does not exist, but is required to operate");
this.options = Object.extend({
exclude: ""
}, options || {});
// define required listeners
this.pwdinput.observe("keyup", this.onChange.bind(this));
},
// handle changes to password
onChange: function( event ) {
// remove chars not to be included or to be excluded
if (Object.isString(this.options.exclude))
this.options.exclude.toArray().each((function(n) {
this.pwdinput.value = $F(this.pwdinput).gsub(n, "");
}).bind(this));
else if (this.options.exclude != null)
this.pwdinput.value = $F(this.pwdinput).gsub(this.options.exclude, "");
// last - call callback back ;) - that is, if defined
if (typeof(this.options.onChange) == "function")
this.options.onChange(this.pwdinput, PwdMeter.getStrength($F(this.pwdinput)));
}
});
// calculates the password's strength
PwdMeter.getStrength = function(pwd) {
pwd = pwd || "";
// empty: weaker than weak ;)
if (pwd == "") return 0.0;
// detects runs, e.g. abcd, aaa, 123 ... considered very weak!
function detectRuns() {
var cc = pwd.toArray().map(function(n) { return (n.toLowerCase().charCodeAt(0) + n.toUpperCase().charCodeAt(0)) / 2; }),
deltas = cc.length - 1,
deltasum = 0;
console.log(cc);
if (deltas < 1) return 0.1;
while (deltas > 0)
deltasum += Math.abs(cc[deltas] - cc[--deltas]);
return Math.min(deltasum / ((cc.length - 1) * 10), 1.0);
}
// detect and proper respect count of l(ower)case, u(pper)case characters, cyphers and special (any other) chars
function charCount() {
return (((pwd.match(/[a-z]/g) || "").length * 0.7)
+ ((pwd.match(/[A-Z]/g) || "").length * 0.7)
+ ((pwd.match(/[0-9]/g) || "").length * 0.9)
+ ((pwd.gsub(/[a-zA-Z0-9]/, "") || "").length * 1.0)) / pwd.length;
}
// return calculated strength, take abs. length into account (the longer, the better)
return detectRuns() * charCount() * (pwd.length < 5 ? 0.25 : (pwd.length < 10 ? 0.5 : 1));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment