├── bower.json ├── README.md ├── jquery.complexify.min.js ├── jquery.complexify.banlist.js └── jquery.complexify.js /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery.complexify", 3 | "version": "0.5.1", 4 | "main": "jquery.complexify.js", 5 | "ignore": [ 6 | "jquery.complexify.min.js" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Complexify 2 | ==================== 3 | 4 | Websites have a responsibility to accurately inform users of password strength, both to better secure data, and to educate about users of what constitutes a good password. 5 | 6 | Complexify aims to provide a good measure of password complexity for websites to use both for giving hints to users in the form of strength bars, and for *casually* enforcing a minimum complexity for security reasons. 7 | 8 | This plugin only provides client-side validation, and should be combined with some server-side sanity checking. If you want a full-blown Complexify implementation for the server, check out the list of ports. 9 | 10 | For more information, a demo, documentation, and the motivation behind Complexify, [visit the website](http://danpalmer.me/jquery-complexify). 11 | 12 | ### Contributing 13 | 14 | Contributions are always welcome! If you're uncertain about something, open a PR and we can discuss. Always feel free to ping me for an update on a merge, reminding me isn't rude, it's helpful. 15 | 16 | 17 | ### Alternative Implementations 18 | 19 | Several people have kindly open-sourced their implementations of this algorithm in other languages: 20 | 21 | - Mert Dümenci [Complexify-Objc](https://github.com/mertdumenci/Complexify-ObjC) 22 | - Andrey Kislyuk [node-complexify](https://github.com/kislyuk/node-complexify) 23 | - Michael Crumley [php-complexify](https://github.com/mcrumley/php-complexify/) 24 | - Maciej Podsiedlak [angular-complexify](https://github.com/Kraku/angular-complexify/) 25 | 26 | - - - 27 | 28 | **This code is distributed under the WTFPL v2 licence.** 29 | -------------------------------------------------------------------------------- /jquery.complexify.min.js: -------------------------------------------------------------------------------- 1 | !function(a){a.fn.extend({complexify:function(b,c){function h(a,b){for(var c=a.length-1;c>=0;c--)if(b[0]<=a.charCodeAt(c)&&a.charCodeAt(c)<=b[1])return b[1]-b[0]+1;return 0}function i(c){if("strict"===b.banMode){for(var d=0;d-1?!0:!1}function j(){var g=a(this).val(),j=0,k=!1;if(i(g))j=1;else for(var l=f.length-1;l>=0;l--)j+=h(g,f[l]);j=Math.log(Math.pow(j,g.length))*(1/b.strengthScaleFactor),k=j>d&&g.length>=b.minimumChars,j=100*(j/e),j=j>100?100:j,c.call(this,k,j)}var d=49,e=120,f=[[32,32],[48,57],[65,90],[97,122],[33,47],[58,64],[91,96],[123,126],[128,255],[256,383],[384,591],[592,687],[688,767],[768,879],[880,1023],[1024,1279],[1328,1423],[1424,1535],[1536,1791],[1792,1871],[1920,1983],[2304,2431],[2432,2559],[2560,2687],[2688,2815],[2816,2943],[2944,3071],[3072,3199],[3200,3327],[3328,3455],[3456,3583],[3584,3711],[3712,3839],[3840,4095],[4096,4255],[4256,4351],[4352,4607],[4608,4991],[5024,5119],[5120,5759],[5760,5791],[5792,5887],[6016,6143],[6144,6319],[7680,7935],[7936,8191],[8192,8303],[8304,8351],[8352,8399],[8400,8447],[8448,8527],[8528,8591],[8592,8703],[8704,8959],[8960,9215],[9216,9279],[9280,9311],[9312,9471],[9472,9599],[9600,9631],[9632,9727],[9728,9983],[9984,10175],[10240,10495],[11904,12031],[12032,12255],[12272,12287],[12288,12351],[12352,12447],[12448,12543],[12544,12591],[12592,12687],[12688,12703],[12704,12735],[12800,13055],[13056,13311],[13312,19893],[19968,40959],[40960,42127],[42128,42191],[44032,55203],[55296,56191],[56192,56319],[56320,57343],[57344,63743],[63744,64255],[64256,64335],[64336,65023],[65056,65071],[65072,65103],[65104,65135],[65136,65278],[65279,65279],[65280,65519],[65520,65533]],g={minimumChars:8,strengthScaleFactor:1,bannedPasswords:window.COMPLEXIFY_BANLIST||[],banMode:"strict"};return a.isFunction(b)&&!c&&(c=b,b={}),b=a.extend(g,b),this.each(function(){a(this).val()&&j.apply(this)}),this.each(function(){a(this).bind("keyup focus input propertychange mouseup",j)})}})}(jQuery); -------------------------------------------------------------------------------- /jquery.complexify.banlist.js: -------------------------------------------------------------------------------- 1 | /* 2 | Generated from 500 worst passwords and 401 banned twiiter passwords as of 20150520. 3 | @source http://www.skullsecurity.org/wiki/index.php/Passwords 4 | 5 | Filtered to remove any passwords shorter than 4 characters, as these will cause 6 | unwanted behaviour when in strict banning mode. 7 | */ 8 | COMPLEXIFY_BANLIST = '000000|111111|11111111|112233|121212|123123|123456|1234567|12345678|123456789|131313|232323|654321|666666|696969|777777|7777777|8675309|987654|nnnnnn|nop123|nopqrs|noteglh|npprff|npprff14|npgvba|nyoreg|nyoregb|nyrkvf|nyrwnaqen|nyrwnaqeb|nznaqn|nzngrhe|nzrevpn|naqern|naqerj|natryn|natryf|navzny|nagubal|ncbyyb|nccyrf|nefrany|neguhe|nfqstu|nfuyrl|nffubyr|nhthfg|nhfgva|onqobl|onvyrl|onanan|onearl|onfronyy|ongzna|orngevm|ornire|ornivf|ovtpbpx|ovtqnqql|ovtqvpx|ovtqbt|ovtgvgf|oveqvr|ovgpurf|ovgrzr|oynmre|oybaqr|oybaqrf|oybjwbo|oybjzr|obaq007|obavgn|obaavr|obbobb|obbtre|obbzre|obfgba|oenaqba|oenaql|oenirf|oenmvy|oebapb|oebapbf|ohyyqbt|ohfgre|ohggre|ohggurnq|pnyiva|pnzneb|pnzreba|pnanqn|pncgnva|pneybf|pnegre|pnfcre|puneyrf|puneyvr|purrfr|puryfrn|purfgre|puvpntb|puvpxra|pbpnpbyn|pbssrr|pbyyrtr|pbzcnd|pbzchgre|pbafhzre|pbbxvr|pbbcre|pbeirggr|pbjobl|pbjoblf|pelfgny|phzzvat|phzfubg|qnxbgn|qnyynf|qnavry|qnavryyr|qroovr|qraavf|qvnoyb|qvnzbaq|qbpgbe|qbttvr|qbycuva|qbycuvaf|qbanyq|qentba|qernzf|qevire|rntyr1|rntyrf|rqjneq|rvafgrva|rebgvp|rfgeryyn|rkgerzr|snypba|sraqre|sreenev|sveroveq|svfuvat|sybevqn|sybjre|sylref|sbbgonyy|sberire|serqql|serrqbz|shpxrq|shpxre|shpxvat|shpxzr|shpxlbh|tnaqnys|tngrjnl|tngbef|trzvav|trbetr|tvnagf|tvatre|tvmzbqb|tbyqra|tbysre|tbeqba|tertbel|thvgne|thaare|unzzre|unaanu|uneqpber|uneyrl|urngure|uryczr|uragnv|ubpxrl|ubbgref|ubearl|ubgqbt|uhagre|uhagvat|vprzna|vybirlbh|vagrearg|vjnagh|wnpxvr|wnpxfba|wnthne|wnfzvar|wnfcre|wraavsre|wrerzl|wrffvpn|wbuaal|wbuafba|wbeqna|wbfrcu|wbfuhn|whavbe|whfgva|xvyyre|xavtug|ynqvrf|ynxref|ynhera|yrngure|yrtraq|yrgzrva|yvggyr|ybaqba|ybiref|znqqbt|znqvfba|znttvr|zntahz|znevar|znevcbfn|zneyobeb|znegva|zneiva|znfgre|zngevk|znggurj|znirevpx|znkjryy|zryvffn|zrzore|zreprqrf|zreyva|zvpunry|zvpuryyr|zvpxrl|zvqavtug|zvyyre|zvfgerff|zbavpn|zbaxrl|zbafgre|zbetna|zbgure|zbhagnva|zhssva|zhecul|zhfgnat|anxrq|anfpne|anguna|anhtugl|app1701|arjlbex|avpubynf|avpbyr|avccyr|avccyrf|byvire|benatr|cnpxref|cnagure|cnagvrf|cnexre|cnffjbeq|cnffjbeq1|cnffjbeq12|cnffjbeq123|cngevpx|crnpurf|crnahg|crccre|cunagbz|cubravk|cynlre|cyrnfr|cbbxvr|cbefpur|cevapr|cevaprff|cevingr|checyr|chffvrf|dnmjfk|djregl|djreglhv|enoovg|enpury|enpvat|envqref|envaobj|enatre|enatref|erorppn|erqfxvaf|erqfbk|erqjvatf|evpuneq|eboreg|eboregb|ebpxrg|ebfrohq|ehaare|ehfu2112|ehffvn|fnznagun|fnzzl|fnzfba|fnaqen|fnghea|fpbbol|fpbbgre|fpbecvb|fpbecvba|fronfgvna|frperg|frkfrk|funqbj|funaaba|funirq|fvreen|fvyire|fxvccl|fynlre|fzbxrl|fabbcl|fbppre|fbcuvr|fcnaxl|fcnexl|fcvqre|fdhveg|fevavinf|fgnegerx|fgnejnef|fgrryref|fgrira|fgvpxl|fghcvq|fhpprff|fhpxvg|fhzzre|fhafuvar|fhcrezna|fhesre|fjvzzvat|flqarl|grdhvreb|gnlybe|graavf|grerfn|grfgre|grfgvat|gurzna|gubznf|guhaqre|guk1138|gvssnal|gvtref|gvttre|gbzpng|gbctha|gblbgn|genivf|gebhoyr|gehfgab1|ghpxre|ghegyr|gjvggre|havgrq|intvan|ivpgbe|ivpgbevn|ivxvat|ibbqbb|iblntre|jnygre|jneevbe|jrypbzr|jungrire|jvyyvnz|jvyyvr|jvyfba|jvaare|jvafgba|jvagre|jvmneq|knivre|kkkkkk|kkkkkkkk|lnznun|lnaxrr|lnaxrrf|lryybj|mkpioa|mkpioaz|mmmmmm|password|1234|pussy|12345|dragon|qwerty|mustang|letmein|baseball|master|michael|football|shadow|monkey|abc123|pass|fuckme|6969|jordan|harley|ranger|iwantu|jennifer|hunter|fuck|2000|test|batman|trustno1|thomas|tigger|robert|access|love|buster|soccer|hockey|killer|george|sexy|andrew|charlie|superman|asshole|fuckyou|dallas|jessica|panties|pepper|1111|austin|william|daniel|golfer|summer|heather|hammer|yankees|joshua|maggie|biteme|enter|ashley|thunder|cowboy|silver|richard|fucker|orange|merlin|michelle|corvette|bigdog|cheese|matthew|patrick|martin|freedom|ginger|blowjob|nicole|sparky|yellow|camaro|secret|dick|falcon|taylor|bitch|hello|scooter|please|porsche|guitar|chelsea|black|diamond|nascar|jackson|cameron|computer|amanda|wizard|xxxxxxxx|money|phoenix|mickey|bailey|knight|iceman|tigers|purple|andrea|horny|dakota|aaaaaa|player|sunshine|morgan|starwars|boomer|cowboys|edward|charles|girls|booboo|coffee|xxxxxx|bulldog|ncc1701|rabbit|peanut|john|johnny|gandalf|spanky|winter|brandy|compaq|carlos|tennis|james|mike|brandon|fender|anthony|blowme|ferrari|cookie|chicken|maverick|chicago|joseph|diablo|sexsex|hardcore|willie|welcome|chris|panther|yamaha|justin|banana|driver|marine|angels|fishing|david|maddog|hooters|wilson|butthead|dennis|fucking|captain|bigdick|chester|smokey|xavier|steven|viking|snoopy|blue|eagles|winner|samantha|house|miller|flower|jack|firebird|butter|united|turtle|steelers|tiffany|zxcvbn|tomcat|golf|bond007|bear|tiger|doctor|gateway|gators|angel|junior|thx1138|porno|badboy|debbie|spider|melissa|booger|1212|flyers|fish|porn|matrix|teens|scooby|jason|walter|cumshot|boston|braves|yankee|lover|barney|victor|tucker|princess|mercedes|5150|doggie|zzzzzz|gunner|horney|bubba|2112|fred|johnson|xxxxx|tits|member|boobs|donald|bigdaddy|bronco|penis|voyager|rangers|birdie|trouble|white|topgun|bigtits|bitches|green|super|qazwsx|magic|lakers|rachel|slayer|scott|2222|asdf|video|london|7777|marlboro|srinivas|internet|action|carter|jasper|monster|teresa|jeremy|bill|crystal|peter|pussies|cock|beer|rocket|theman|oliver|prince|beach|amateur|muffin|redsox|star|testing|shannon|murphy|frank|hannah|dave|eagle1|11111|mother|nathan|raiders|steve|forever|angela|viper|ou812|jake|lovers|suckit|gregory|buddy|whatever|young|nicholas|lucky|helpme|jackie|monica|midnight|college|baby|cunt|brian|mark|startrek|sierra|leather|4444|beavis|bigcock|happy|sophie|ladies|naughty|giants|booty|blonde|fucked|golden|fire|sandra|pookie|packers|einstein|dolphins|chevy|winston|warrior|sammy|slut|zxcvbnm|nipples|power|victoria|asdfgh|vagina|toyota|travis|hotdog|paris|rock|xxxx|extreme|redskins|erotic|dirty|ford|freddy|arsenal|access14|wolf|nipple|iloveyou|alex|florida|eric|legend|movie|success|rosebud|jaguar|great|cool|cooper|1313|scorpio|mountain|madison|brazil|lauren|japan|naked|squirt|stars|apple|alexis|aaaa|bonnie|peaches|jasmine|kevin|matt|qwertyui|danielle|beaver|4321|4128|runner|swimming|dolphin|gordon|casper|stupid|shit|saturn|gemini|apples|august|3333|canada|blazer|cumming|hunting|kitty|rainbow|arthur|cream|calvin|shaved|surfer|samson|kelly|paul|mine|king|racing|5555|eagle|hentai|newyork|little|redwings|smith|sticky|cocacola|animal|broncos|private|skippy|marvin|blondes|enjoy|girl|apollo|parker|qwert|time|sydney|women|voodoo|magnum|juice|abgrtyu|dreams|maxwell|music|rush2112|russia|scorpion|rebecca|tester|mistress|phantom|billy|6666|albert|abcdef|password1|password12|password123|twitter'.split('|'); 9 | -------------------------------------------------------------------------------- /jquery.complexify.js: -------------------------------------------------------------------------------- 1 | /* 2 | http://github.com/danpalmer/jquery.complexify.js 3 | 4 | This code is distributed under the WTFPL v2: 5 | */ 6 | (function ($) { 7 | 8 | $.fn.extend({ 9 | complexify: function(options, callback) { 10 | 11 | var MIN_COMPLEXITY = 49; // 12 chars with Upper, Lower and Number 12 | var MAX_COMPLEXITY = 120; // 25 chars, all charsets 13 | var CHARSETS = [ 14 | // Commonly Used 15 | //////////////////// 16 | [0x0020, 0x0020], // Space 17 | [0x0030, 0x0039], // Numbers 18 | [0x0041, 0x005A], // Uppercase 19 | [0x0061, 0x007A], // Lowercase 20 | [0x0021, 0x002F], // Punctuation 21 | [0x003A, 0x0040], // Punctuation 22 | [0x005B, 0x0060], // Punctuation 23 | [0x007B, 0x007E], // Punctuation 24 | // Everything Else 25 | //////////////////// 26 | [0x0080, 0x00FF], // Latin-1 Supplement 27 | [0x0100, 0x017F], // Latin Extended-A 28 | [0x0180, 0x024F], // Latin Extended-B 29 | [0x0250, 0x02AF], // IPA Extensions 30 | [0x02B0, 0x02FF], // Spacing Modifier Letters 31 | [0x0300, 0x036F], // Combining Diacritical Marks 32 | [0x0370, 0x03FF], // Greek 33 | [0x0400, 0x04FF], // Cyrillic 34 | [0x0530, 0x058F], // Armenian 35 | [0x0590, 0x05FF], // Hebrew 36 | [0x0600, 0x06FF], // Arabic 37 | [0x0700, 0x074F], // Syriac 38 | [0x0780, 0x07BF], // Thaana 39 | [0x0900, 0x097F], // Devanagari 40 | [0x0980, 0x09FF], // Bengali 41 | [0x0A00, 0x0A7F], // Gurmukhi 42 | [0x0A80, 0x0AFF], // Gujarati 43 | [0x0B00, 0x0B7F], // Oriya 44 | [0x0B80, 0x0BFF], // Tamil 45 | [0x0C00, 0x0C7F], // Telugu 46 | [0x0C80, 0x0CFF], // Kannada 47 | [0x0D00, 0x0D7F], // Malayalam 48 | [0x0D80, 0x0DFF], // Sinhala 49 | [0x0E00, 0x0E7F], // Thai 50 | [0x0E80, 0x0EFF], // Lao 51 | [0x0F00, 0x0FFF], // Tibetan 52 | [0x1000, 0x109F], // Myanmar 53 | [0x10A0, 0x10FF], // Georgian 54 | [0x1100, 0x11FF], // Hangul Jamo 55 | [0x1200, 0x137F], // Ethiopic 56 | [0x13A0, 0x13FF], // Cherokee 57 | [0x1400, 0x167F], // Unified Canadian Aboriginal Syllabics 58 | [0x1680, 0x169F], // Ogham 59 | [0x16A0, 0x16FF], // Runic 60 | [0x1780, 0x17FF], // Khmer 61 | [0x1800, 0x18AF], // Mongolian 62 | [0x1E00, 0x1EFF], // Latin Extended Additional 63 | [0x1F00, 0x1FFF], // Greek Extended 64 | [0x2000, 0x206F], // General Punctuation 65 | [0x2070, 0x209F], // Superscripts and Subscripts 66 | [0x20A0, 0x20CF], // Currency Symbols 67 | [0x20D0, 0x20FF], // Combining Marks for Symbols 68 | [0x2100, 0x214F], // Letterlike Symbols 69 | [0x2150, 0x218F], // Number Forms 70 | [0x2190, 0x21FF], // Arrows 71 | [0x2200, 0x22FF], // Mathematical Operators 72 | [0x2300, 0x23FF], // Miscellaneous Technical 73 | [0x2400, 0x243F], // Control Pictures 74 | [0x2440, 0x245F], // Optical Character Recognition 75 | [0x2460, 0x24FF], // Enclosed Alphanumerics 76 | [0x2500, 0x257F], // Box Drawing 77 | [0x2580, 0x259F], // Block Elements 78 | [0x25A0, 0x25FF], // Geometric Shapes 79 | [0x2600, 0x26FF], // Miscellaneous Symbols 80 | [0x2700, 0x27BF], // Dingbats 81 | [0x2800, 0x28FF], // Braille Patterns 82 | [0x2E80, 0x2EFF], // CJK Radicals Supplement 83 | [0x2F00, 0x2FDF], // Kangxi Radicals 84 | [0x2FF0, 0x2FFF], // Ideographic Description Characters 85 | [0x3000, 0x303F], // CJK Symbols and Punctuation 86 | [0x3040, 0x309F], // Hiragana 87 | [0x30A0, 0x30FF], // Katakana 88 | [0x3100, 0x312F], // Bopomofo 89 | [0x3130, 0x318F], // Hangul Compatibility Jamo 90 | [0x3190, 0x319F], // Kanbun 91 | [0x31A0, 0x31BF], // Bopomofo Extended 92 | [0x3200, 0x32FF], // Enclosed CJK Letters and Months 93 | [0x3300, 0x33FF], // CJK Compatibility 94 | [0x3400, 0x4DB5], // CJK Unified Ideographs Extension A 95 | [0x4E00, 0x9FFF], // CJK Unified Ideographs 96 | [0xA000, 0xA48F], // Yi Syllables 97 | [0xA490, 0xA4CF], // Yi Radicals 98 | [0xAC00, 0xD7A3], // Hangul Syllables 99 | [0xD800, 0xDB7F], // High Surrogates 100 | [0xDB80, 0xDBFF], // High Private Use Surrogates 101 | [0xDC00, 0xDFFF], // Low Surrogates 102 | [0xE000, 0xF8FF], // Private Use 103 | [0xF900, 0xFAFF], // CJK Compatibility Ideographs 104 | [0xFB00, 0xFB4F], // Alphabetic Presentation Forms 105 | [0xFB50, 0xFDFF], // Arabic Presentation Forms-A 106 | [0xFE20, 0xFE2F], // Combining Half Marks 107 | [0xFE30, 0xFE4F], // CJK Compatibility Forms 108 | [0xFE50, 0xFE6F], // Small Form Variants 109 | [0xFE70, 0xFEFE], // Arabic Presentation Forms-B 110 | [0xFEFF, 0xFEFF], // Specials 111 | [0xFF00, 0xFFEF], // Halfwidth and Fullwidth Forms 112 | [0xFFF0, 0xFFFD] // Specials 113 | ]; 114 | 115 | var defaults = { 116 | minimumChars: 8, 117 | strengthScaleFactor: 1, 118 | bannedPasswords: window.COMPLEXIFY_BANLIST || [], 119 | banMode: 'strict' // (strict|loose) 120 | }; 121 | 122 | if($.isFunction(options) && !callback) { 123 | callback = options; 124 | options = {}; 125 | } 126 | 127 | options = $.extend(defaults, options); 128 | 129 | function additionalComplexityForCharset(str, charset) { 130 | for (var i = str.length - 1; i >= 0; i--) { 131 | if (charset[0] <= str.charCodeAt(i) && str.charCodeAt(i) <= charset[1]) { 132 | return charset[1] - charset[0] + 1; 133 | } 134 | } 135 | return 0; 136 | } 137 | 138 | function inBanlist(str) { 139 | if (options.banMode === 'strict') { 140 | for (var i = 0; i < options.bannedPasswords.length; i++) { 141 | if (str.toLowerCase().indexOf(options.bannedPasswords[i].toLowerCase()) !== -1) { 142 | return true; 143 | } 144 | } 145 | return false; 146 | } else { 147 | return $.inArray(str, options.bannedPasswords) > -1 ? true : false; 148 | } 149 | } 150 | 151 | function evaluateSecurity() { 152 | var password = $(this).val(); 153 | var complexity = 0, valid = false; 154 | 155 | // Reset complexity to 0 when banned password is found 156 | if (!inBanlist(password)) { 157 | 158 | // Add character complexity 159 | for (var i = CHARSETS.length - 1; i >= 0; i--) { 160 | complexity += additionalComplexityForCharset(password, CHARSETS[i]); 161 | } 162 | 163 | } else { 164 | complexity = 1; 165 | } 166 | 167 | // Use natural log to produce linear scale 168 | complexity = Math.log(Math.pow(complexity, password.length)) * (1/options.strengthScaleFactor); 169 | 170 | valid = (complexity > MIN_COMPLEXITY && password.length >= options.minimumChars); 171 | 172 | // Scale to percentage, so it can be used for a progress bar 173 | complexity = (complexity / MAX_COMPLEXITY) * 100; 174 | complexity = (complexity > 100) ? 100 : complexity; 175 | 176 | callback.call(this, valid, complexity); 177 | } 178 | 179 | this.each(function () { 180 | if($(this).val()) { 181 | evaluateSecurity.apply(this); 182 | } 183 | }); 184 | 185 | return this.each(function () { 186 | $(this).bind('keyup focus input propertychange mouseup', evaluateSecurity); 187 | }); 188 | 189 | } 190 | }); 191 | 192 | })(jQuery); 193 | --------------------------------------------------------------------------------