Created
May 8, 2010 15:41
-
-
Save ta2edchimp/394613 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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