(function(){ var MULTIPLE_NUMBERS_RE = /\d.*?\d.*?\d/; var MULTIPLE_SYMBOLS_RE = /[!@#$%^&*?_~].*?[!@#$%^&*?_~]/; var UPPERCASE_LOWERCASE_RE = /([a-z].*[A-Z])|([A-Z].*[a-z])/; var SYMBOL_RE = /[!@#\$%^&*?_~]/; function escapeForRegexp(string) { return (string || "").replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } function PasswordStrength() { this.username = null; this.password = null; this.score = 0; this.status = null; } PasswordStrength.fn = PasswordStrength.prototype; PasswordStrength.fn.test = function() { var score; this.score = score = 0; if (this.containInvalidMatches()) { this.status = "invalid"; } else if (this.usesCommonWord()) { this.status = "invalid"; } else if (this.containInvalidRepetition()) { this.status = "invalid"; } else { score += this.scoreFor("password_size"); score += this.scoreFor("numbers"); score += this.scoreFor("symbols"); score += this.scoreFor("uppercase_lowercase"); score += this.scoreFor("numbers_chars"); score += this.scoreFor("numbers_symbols"); score += this.scoreFor("symbols_chars"); score += this.scoreFor("only_chars"); score += this.scoreFor("only_numbers"); score += this.scoreFor("username"); score += this.scoreFor("sequences"); score += this.scoreFor("repetitions"); if (score < 0) { score = 0; } if (score > 100) { score = 100; } if (score < 35) { this.status = "weak"; } if (score >= 35 && score < 70) { this.status = "good"; } if (score >= 70) { this.status = "strong"; } } this.score = score; return this.score; }; PasswordStrength.fn.scoreFor = function(name) { var score = 0; switch (name) { case "password_size": if (this.password.length < 6) { score = -100; } else { score = this.password.length * 4; } break; case "numbers": if (this.password.match(MULTIPLE_NUMBERS_RE)) { score = 5; } break; case "symbols": if (this.password.match(MULTIPLE_SYMBOLS_RE)) { score = 5; } break; case "uppercase_lowercase": if (this.password.match(UPPERCASE_LOWERCASE_RE)) { score = 10; } break; case "numbers_chars": if (this.password.match(/[a-z]/i) && this.password.match(/[0-9]/)) { score = 15; } break; case "numbers_symbols": if (this.password.match(/[0-9]/) && this.password.match(SYMBOL_RE)) { score = 15; } break; case "symbols_chars": if (this.password.match(/[a-z]/i) && this.password.match(SYMBOL_RE)) { score = 15; } break; case "only_chars": if (this.password.match(/^[a-z]+$/i)) { score = -15; } break; case "only_numbers": if (this.password.match(/^\d+$/i)) { score = -15; } break; case "username": if (this.password == this.username) { score = -100; } else if (this.password.indexOf(this.username) != -1) { score = -15; } break; case "sequences": score += -15 * this.sequences(this.password); score += -15 * this.sequences(this.reversed(this.password)); break; case "repetitions": score += -(this.repetitions(this.password, 2) * 4); score += -(this.repetitions(this.password, 3) * 3); score += -(this.repetitions(this.password, 4) * 2); break; }; return score; }; PasswordStrength.fn.isGood = function() { return this.status == "good"; }; PasswordStrength.fn.isWeak = function() { return this.status == "weak"; }; PasswordStrength.fn.isStrong = function() { return this.status == "strong"; }; PasswordStrength.fn.isInvalid = function() { return this.status == "invalid"; }; PasswordStrength.fn.isValid = function(level) { if(level == "strong") { return this.isStrong(); } else if (level == "good") { return this.isStrong() || this.isGood(); } else { return !this.containInvalidMatches() && !this.usesCommonWord(); } }; PasswordStrength.fn.containInvalidMatches = function() { if (!this.exclude) { return false; } if (!this.exclude.test) { return false; } return this.exclude.test(this.password.toString()); }; PasswordStrength.fn.containInvalidRepetition = function() { var char = this.password[0]; if (!char) { return; } var regex = new RegExp("^" + escapeForRegexp(char) + "+$", "i"); return regex.test(this.password); }; PasswordStrength.fn.usesCommonWord = function() { return PasswordStrength.commonWords.indexOf(this.password.toLowerCase()) >= 0; }; PasswordStrength.fn.sequences = function(text) { var matches = 0; var sequenceSize = 0; var codes = []; var len = text.length; var previousCode, currentCode; for (var i = 0; i < len; i++) { currentCode = text.charCodeAt(i); previousCode = codes[codes.length - 1]; codes.push(currentCode); if (previousCode) { if (currentCode == previousCode + 1 || previousCode == currentCode) { sequenceSize += 1; } else { sequenceSize = 0; } } if (sequenceSize == 2) { matches += 1; } } return matches; }; PasswordStrength.fn.repetitions = function(text, size) { var count = 0; var matches = {}; var len = text.length; var substring; var occurrences; var tmpText; for (var i = 0; i < len; i++) { substring = text.substr(i, size); occurrences = 0; tmpText = text; if (matches[substring] || substring.length < size) { continue; } matches[substring] = true; while ((i = tmpText.indexOf(substring)) != -1) { occurrences += 1; tmpText = tmpText.substr(i + 1); }; if (occurrences > 1) { count += 1; } } return count; }; PasswordStrength.fn.reversed = function(text) { var newText = ""; var len = text.length; for (var i = len -1; i >= 0; i--) { newText += text.charAt(i); } return newText; }; PasswordStrength.test = function(username, password) { var strength = new PasswordStrength(); strength.username = username; strength.password = password; strength.test(); return strength; }; PasswordStrength.commonWords = ["!qaz1qaz", "!qaz2wsx", "!qazxsw2", "!qazzaq1", "#edc4rfv", "000000", "010203", "1111", "11111", "111111", "11111111", "112233", "1212", "121212", "123123", "1234", "12345", "123456", "1234567", "12345678", "123456789", "1234567890", "123qweasd", "12qw!@qw", "1313", "131313", "1941.salembbb.41", "1qaz!qaz", "1qaz2wsx", "1qaz@wsx", "1qazxsw@", "1qazzaq!", "2000", "2112", "2222", "232323", "2wsx@wsx", "3333", "3edc#edc", "4128", "4321", "4444", "5150", "5555", "55555", "555555", "654321", "6666", "666666", "6969", "696969", "7777", "777777", "7777777", "8675309", "987654", "987654321", "@wsx2wsx", "aaaa", "aaaaaa", "aaliyah1", "abc123", "abc123abc", "abcabc123", "abcd1234", "abcdef", "abgrtyu", "abigail1", "access", "access14", "action", "addison1", "admin", "adobe123", "affair", "airforce1", "alabama1", "albert", "alex", "alexander1", "alexandra1", "alexis", "allison1", "amanda", "amateur", "america1", "anderson1", "andrea", "andrew", "angel", "angel101", "angel123", "angela", "angelina1", "angels", "animal", "annabelle1", "anthony", "anthony1", "anthony11", "antonio1", "apollo", "apple", "apples", "arianna1", "arsenal", "arsenal1", "arsenal12", "arsenal123", "arthur", "asdf", "asdfasdf", "asdfg", "asdfgh", "asdfghjkl", "ashley", "ashley12", "asshole", "asshole1", "atlanta1", "august", "august08", "august10", "august12", "august20", "august22", "austin", "austin02", "austin316", "australia1", "awesome1", "azerty", "baby", "babyboy1", "babygirl1", "babygurl1", "badboy", "bailey", "bailey12", "banana", "barcelona1", "barney", "baseball", "baseball1", "batista1", "batman", "beach", "bear", "beautiful1", "beaver", "beavis", "beckham7", "beer", "bella123", "benjamin1", "bentley1", "bethany1", "bigcock", "bigdaddy", "bigdaddy1", "bigdick", "bigdog", "bigtits", "bill", "billy", "birdie", "bitch", "bitches", "biteme", "black", "blazer", "blessed1", "blink-182", "blink182", "blonde", "blondes", "blondie1", "blowjob", "blowme", "blue", "bond007", "bonnie", "booboo", "boobs", "booger", "boomer", "booty", "boricua1", "boston", "bradley1", "brandon", "brandon1", "brandon2", "brandon7", "brandy", "braves", "braxton1", "brayden1", "brazil", "breanna1", "brian", "brianna1", "brittany1", "brittney1", "bronco", "broncos", "broncos1", "brooklyn1", "brownie1", "bubba", "bubbles1", "buddy", "buddy123", "bulldog", "buster", "butter", "buttercup1", "butterfly1", "butterfly7", "butthead", "buttons1", "calvin", "camaro", "cameron", "cameron1", "canada", "candy123", "captain", "carlos", "carolina1", "carter", "casper", "cassandra1", "catherine1", "celtic1888", "chargers1", "charles", "charles1", "charlie", "charlie1", "charlotte1", "charmed1", "cheese", "chelsea", "chelsea1", "chelsea123", "chester", "chester1", "chevy", "cheyenne1", "chicago", "chicago1", "chicken", "chicken1", "chocolate1", "chopper1", "chris", "chris123", "christian1", "christina1", "christine1", "christmas1", "classof08", "clayton1", "cocacola", "cock", "coffee", "college", "college1", "colombia1", "colorado1", "compaq", "computer", "computer1", "cookie", "cool", "cooper", "corvette", "courtney1", "cowboy", "cowboys", "cowboys1", "cream", "cricket1", "crystal", "crystal1", "cumming", "cumshot", "cunt", "cutiepie1", "daisy123", "dakota", "dallas", "dallas22", "dan1elle", "daniel", "daniela1", "danielle", "danielle1", "dave", "david", "david123", "death666", "debbie", "december1", "december21", "DEFAULT", "dennis", "derrick1", "destiny1", "deuseamor", "devil666", "diablo", "diamond", "diamond1", "diamonds1", "dick", "dirty", "doctor", "doggie", "dolphin", "dolphin1", "dolphins", "dolphins1", "dominic1", "donald", "douglas1", "dragon", "dreams", "driver", "eagle", "eagle1", "eagles", "edward", "einstein", "elizabeth1", "elizabeth2", "england1", "enjoy", "enter", "eric", "erotic", "extreme", "falcon", "falcons1", "falcons7", "familia", "fender", "ferrari", "fire", "firebird", "fish", "fishing", "florida", "florida1", "flower", "flyers", "football", "football1", "ford", "forever", "forever1", "forever21", "formula1", "frank", "frankie1", "fred", "freddie1", "freddy", "freedom", "freedom1", "friday13", "friends1", "friends2", "fuck", "fucked", "fucker", "fucking", "fuckme", "fuckoff", "fuckoff1", "fuckyou", "fuckyou1", "fuckyou2", "gabriel1", "gandalf", "gangsta1", "garrett1", "gateway", "gateway1", "gators", "gemini", "genesis1", "george", "georgia1", "gerrard8", "giants", "giggles1", "ginger", "girl", "girls", "goddess1", "godislove1", "golden", "golf", "golfer", "gordon", "gordon24", "grandma1", "great", "green", "greenday1", "gregory", "guitar", "gunner", "hammer", "hannah", "happy", "hardcore", "harley", "harry123", "hawaii50", "heather", "heather1", "hello", "hello123", "helpme", "hentai", "hershey1", "hockey", "holiday1", "hollywood1", "honey123", "hooters", "horney", "horny", "hosts", "hotdog", "house", "houston1", "hunter", "hunter01", "hunting", "iceman", "iloveme1", "iloveme2", "iloveyou", "iloveyou1", "iloveyou2", "internet", "internet1", "inuyasha1", "ireland1", "isabella1", "isabelle1", "iverson3", "iwantu", "iydgtvmujl6f", "jack", "jackie", "jackson", "jackson1", "jackson5", "jaguar", "jake", "jamaica1", "james", "james123", "january1", "january29", "japan", "jasmine", "jasmine1", "jason", "jasper", "jazmine1", "jeffrey1", "jehovah1", "jennifer", "jennifer1", "jennifer2", "jeremiah1", "jeremy", "jessica", "jessica1", "jessica7", "jesus", "jesus123", "jesus143", "jesus1st", "jesus4me", "jesus777", "jesuscristo", "jesusis#1", "jesusis1", "john", "john3:16", "johncena1", "johnny", "johnson", "jonathan1", "jordan", "jordan01", "jordan12", "jordan23", "joseph", "joshua", "joshua01", "juice", "junior", "justice1", "justin", "justin01", "justin11", "justin21", "justin23", "katelyn1", "katherine1", "kathryn1", "katrina1", "kazuga", "kelly", "kendall1", "kennedy1", "kenneth1", "kevin", "killer", "kimberly1", "king", "kitty", "knight", "kristen1", "kristin1", "l6fkiy9on", "ladies", "ladybug1", "lakers", "lakers24", "lampard8", "laura123", "lauren", "leather", "lebron23", "legend", "letmein", "letmein1", "liberty1", "lindsay1", "lindsey1", "little", "liverp00l", "liverpool", "liverpool1", "liverpool123", "london", "longhorns1", "looking", "love", "love4ever", "lover", "lovers", "loveyou2", "lucky", "lucky123", "m1chelle", "mackenzie1", "maddog", "madison", "madison01", "madison1", "madonna1", "maggie", "magic", "magnum", "makayla1", "marcelo", "marie123", "marine", "marines1", "marissa1", "mark", "marlboro", "marshall1", "martin", "marvin", "master", "matrix", "matt", "matthew", "matthew1", "matthew2", "matthew3", "maverick", "maxwell", "maxwell1", "melanie1", "melissa", "melissa1", "member", "mercedes", "mercedes1", "merlin", "metallica1", "michael", "michael01", "michael07", "michael1", "michael2", "michael7", "micheal1", "michele1", "michelle", "michelle1", "michelle2", "mickey", "midnight", "midnight1", "mike", "miller", "mine", "miranda1", "mistress", "molly123", "money", "monica", "monique1", "monkey", "monkey01", "monkey12", "monkey13", "monkeys1", "monster", "monster1", "montana1", "morgan", "mother", "mountain", "movie", "muffin", "murphy", "music", "music123", "mustang", "mustang1", "myspace1", "naked", "nascar", "natalie1", "natasha1", "nathan", "nathan06", "naughty", "ncc1701", "newyork", "newyork1", "nicholas", "nicholas1", "nichole1", "nicole", "nicole12", "ninja", "nipple", "nipples", "nirvana1", "november1", "november11", "november15", "november16", "nursing1", "october1", "october13", "october22", "oliver", "omarion1", "orange", "orlando1", "ou812", "p4ssword", "p@$$w0rd", "p@55w0rd", "p@ssw0rd", "pa$$w0rd", "pa55w0rd", "pa55word", "packers", "panther", "panther1", "panthers1", "panties", "paris", "parker", "pass", "pass1234", "passion1", "passw0rd", "passw0rd1", "password", "password01", "password1", "password1!", "password11", "password12", "password123", "password13", "password2", "password21", "password3", "password4", "password5", "password7", "password9", "patches1", "patricia1", "patrick", "patrick1", "paul", "peaches", "peaches1", "peanut", "peanut01", "peanut11", "pebbles1", "penguin1", "penis", "pepper", "peter", "phantom", "phantom1", "phoenix", "phoenix1", "photoshop", "pickles1", "playboy1", "player", "please", "pokemon1", "poohbear1", "pookie", "popcorn1", "porn", "porno", "porsche", "power", "pr1nc3ss", "pr1ncess", "precious1", "preston1", "prince", "princess", "princess01", "princess07", "princess08", "princess1", "princess12", "princess123", "princess13", "princess15", "princess18", "princess19", "princess2", "princess21", "princess23", "princess24", "princess4", "princess5", "princess7", "private", "prototype1", "pumpkin1", "purple", "pussies", "pussy", "qazwsx", "qwert", "qwerty", "qwerty123", "qwertyui", "qwertyuiop", "rabbit", "rachel", "racing", "raiders", "raiders1", "rainbow", "rainbow1", "ranger", "rangers", "rangers1", "raymond1", "rebecca", "rebecca1", "rebelde1", "redskins", "redskins1", "redsox", "redwings", "ricardo1", "richard", "richard1", "robert", "robert01", "rock", "rocket", "rockstar1", "rocky123", "rockyou1", "ronaldo7", "rosebud", "runner", "rush2112", "russell1", "russia", "rusty123", "sabrina1", "sail2boat3", "samantha", "samantha1", "sammy", "samson", "sandra", "santana1", "saturn", "savannah1", "scooby", "scooter", "scooter1", "scorpio", "scorpio1", "scorpion", "scotland1", "scott", "scrappy1", "sebastian1", "secret", "senior06", "senior07", "september1", "serenity1", "sexsex", "sexy", "shadow", "shannon", "shannon1", "shaved", "shit", "shopping1", "sierra", "silver", "skippy", "skittles1", "slayer", "slipknot1", "slut", "smith", "smokey", "smokey01", "snickers1", "snoopy", "snowball1", "soccer", "soccer11", "soccer12", "soccer13", "soccer14", "soccer17", "softball1", "sophie", "spanky", "sparky", "spartan117", "special1", "spencer1", "spider", "spiderman1", "spongebob1", "squirt", "srinivas", "star", "stars", "start123", "startrek", "starwars", "starwars1", "steelers", "steelers1", "stephanie1", "stephen1", "steve", "steven", "sticky", "stupid", "success", "suckit", "summer", "summer01", "summer05", "summer06", "summer07", "summer08", "summer99", "sunshine", "sunshine1", "super", "superman", "superman1", "superstar1", "surfer", "sweetie1", "sweetpea1", "swimming", "sydney", "taylor", "taylor13", "tbfkiy9on", "teddybear1", "teens", "tennis", "teresa", "test", "tester", "testing", "theman", "thesims2", "thirteen13", "thomas", "thumper1", "thunder", "thunder1", "thx1138", "tiffany", "tiffany1", "tiger", "tiger123", "tigers", "tigger", "tigger01", "tigger12", "tigger123", "time", "timothy1", "tinkerbell1", "titanic1", "tits", "tomcat", "topgun", "toyota", "travis", "trinity1", "trinity3", "tristan1", "trouble", "trouble1", "trustno1", "tucker", "turtle", "twilight1", "twitter", "unicorn1", "united", "vagina", "valerie1", "vampire1", "vanessa1", "vanilla1", "veronica1", "victor", "victoria", "victoria1", "video", "viking", "vincent1", "viper", "voodoo", "voyager", "walter", "warrior", "welcome", "welcome1", "welcome123", "welcome2", "whatever", "whatever1", "white", "whitney1", "william", "william1", "willie", "wilson", "winner", "winston", "winston1", "winter", "winter06", "wizard", "wolf", "women", "xavier", "xxxx", "xxxxx", "xxxxxx", "xxxxxxxx", "yamaha", "yankee", "yankees", "yankees1", "yankees2", "yellow", "young", "z,iyd86i", "zachary1", "zaq!1qaz", "zaq!2wsx", "zaq!xsw2", "zaq1!qaz", "zaq1@wsx", "zaq1zaq!", "zxcvbn", "zxcvbnm", "zzzzzz"]; if (typeof(module) === "object" && module.exports) { module.exports = PasswordStrength; } else if (typeof define === "function" && define.amd) { define("password_strength", [], function() { return PasswordStrength; }); } else if (typeof(window) === "object") { window.PasswordStrength = PasswordStrength; } })();