====== JavaScript - Password validation ====== Validation types supported out of the box. All are optional, which means that all passwords are allowed by default. * Minimum and maximum length. * Minimum n lowercase characters (a–z). * Minimum n uppercase characters (A–Z). * Minimum n combined a–z and A–Z characters. * Minimum n numeric characters (0–9). * Minimum n special characters (characters other than a–z, A–Z, and 0–9). * Ban particular words (tested case-insensitively). * Ban n-length character sequences (e.g. "abc", "XYZ", or "789", with a sequence length of 3; does not apply to special characters). * Ban n-length qwerty character sequences (e.g. "qwerty" or "asdf", with a sequence length of 4; does not apply to special characters). * Ban sequential, identical characters (e.g. "aa" or "!!"). * Use custom regular expressions (tested using RegExp.prototype.test) and functions (the password is provided as the first argument, and a Boolean value is expected in return). Here's an example of how it can be used: var password = "password"; var passed = validatePassword(password, { length: [8, Infinity], lower: 1, upper: 1, numeric: 1, special: 1, badWords: ["password", "steven", "levithan"], badSequenceLength: 4 }); // passed: false The above requires that password is at least eight characters long; has at least one lowercase, uppercase, numeric, and special character; doesn't include the words "password", "steven", or "levithan"; and doesn't include an alphanumeric sequence four or more characters in length (e.g. "1234"). Here's the code (there are no external library dependencies): http://blog.stevenlevithan.com/archives/javascript-password-validator /* Password Validator 0.1 (c) 2007 Steven Levithan MIT License */ function validatePassword (pw, options) { // default options (allows any password) var o = { lower: 0, upper: 0, alpha: 0, /* lower + upper */ numeric: 0, special: 0, length: [0, Infinity], custom: [ /* regexes and/or functions */ ], badWords: [], badSequenceLength: 0, noQwertySequences: false, noSequential: false }; for (var property in options) o[property] = options[property]; var re = { lower: /[a-z]/g, upper: /[A-Z]/g, alpha: /[A-Z]/gi, numeric: /[0-9]/g, special: /[\W_]/g }, rule, i; // enforce min/max length if (pw.length < o.length[0] || pw.length > o.length[1]) return false; // enforce lower/upper/alpha/numeric/special rules for (rule in re) { if ((pw.match(re[rule]) || []).length < o[rule]) return false; } // enforce word ban (case insensitive) for (i = 0; i < o.badWords.length; i++) { if (pw.toLowerCase().indexOf(o.badWords[i].toLowerCase()) > -1) return false; } // enforce the no sequential, identical characters rule if (o.noSequential && /([\S\s])\1/.test(pw)) return false; // enforce alphanumeric/qwerty sequence ban rules if (o.badSequenceLength) { var lower = "abcdefghijklmnopqrstuvwxyz", upper = lower.toUpperCase(), numbers = "0123456789", qwerty = "qwertyuiopasdfghjklzxcvbnm", start = o.badSequenceLength - 1, seq = "_" + pw.slice(0, start); for (i = start; i < pw.length; i++) { seq = seq.slice(1) + pw.charAt(i); if ( lower.indexOf(seq) > -1 || upper.indexOf(seq) > -1 || numbers.indexOf(seq) > -1 || (o.noQwertySequences && qwerty.indexOf(seq) > -1) ) { return false; } } } // enforce custom regex/function rules for (i = 0; i < o.custom.length; i++) { rule = o.custom[i]; if (rule instanceof RegExp) { if (!rule.test(pw)) return false; } else if (rule instanceof Function) { if (!rule(pw)) return false; } } // great success! return true; } Whitespaces will be invalidated if you add the /[\s]/g within the custom regexes declaration. The correct regexp is /^\S+$/g