2 /* ************************************************************
3 Created: 20060120
4 Author: Steve Moitozo <god at zilla dot us>
5 Description: This is a quick and dirty password quality meter
6 written in JavaScript
7 License: MIT License (see below)
8 =================================
9 Revision Author: Dick Ervasti (dick dot ervasti at quty dot com)
10 Revision Description: Exchanged text based prompts for a graphic thermometer
11 =================================
12 Revision Author: Jay Bigam jayb <o> tearupyourlawn <o> com
13 Revision Date: Feb. 26, 2007
14 Revision Description: Changed D. Ervasti's table based "thermometer" to CSS.
15 Revision Notes: - Verified to work in FF2, IE7 and Safari2
16 - Modified messages to reflect Minimum strength requirement
17 - Added formSubmit button disabled until minimum requirement met
18 =================================
19 Modified: 20061111 - Steve Moitozo corrected regex for letters and numbers
20 Thanks to Zack Smith -- zacksmithdesign.com
21 and put MIT License back in
23 ---------------------------------------------------------------
24 Copyright (c) 2006 Steve Moitozo <god at zilla dot us>
26 Permission is hereby granted, free of charge, to any person
27 obtaining a copy of this software and associated documentation
28 files (the "Software"), to deal in the Software without
29 restriction, including without limitation the rights to use,
30 copy, modify, merge, publish, distribute, sublicense, and/or
31 sell copies of the Software, and to permit persons to whom the
32 Software is furnished to do so, subject to the following
33 conditions:
35 The above copyright notice and this permission notice shall
36 be included in all copies or substantial portions of the
37 Software.
39 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
40 KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
41 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
42 AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
43 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
44 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
45 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
46 OR OTHER DEALINGS IN THE SOFTWARE.
47 ---------------------------------------------------------------
49 USAGE:
51 You can play with the pwdTest div style to make it go where you want.
53 In this case it sits to the right side of the input
55 <!-- Code To Add To HTML Form Page -->
57 <!-- the include -->
58 <script type="text/javascript" src="scripts/pwdStrength.js"></script>
60 <!-- the input -->
61 <input type="text" name="password" id="password" onkeyup="testPassword(document.forms.YourFormName.password.value);">
63 <!-- the "meter" -->
64 <div id="pwdTest" style="padding:3px;float:right;font-size:.8em;width:180px;min-width:220;border:1px dashed;margin-top:-40px;">
65 Password Strength:<br>
66 <span id="meterEmpty" style="padding:0;margin:0;width:100%;background-color:##DC143C;display:block;height:5px;">
67 <span id="meterFull" style="padding:0;margin:0;z-index:100;width:0;background-color:##006400;display:block;height:5px;"></span></span>
68 <span id="Words" style="font-size:.8em; margin-top;-25px;">Minimum Strength Not Met</span>
69 </div>
70 <!-- the submit button -->
71 <input disabled type="submit" id ="formSubmit">
72 <!-- End of HTML -->
74 ===================================
75 Password Strength Factors and Weightings
77 password length:
78 level 0 (3 point): less than 4 characters
79 level 1 (6 points): between 5 and 7 characters
80 level 2 (12 points): between 8 and 15 characters
81 level 3 (18 points): 16 or more characters
83 letters:
84 level 0 (0 points): no letters
85 level 1 (5 points): all letters are lower case
86 level 2 (7 points): letters are mixed case
88 numbers:
89 level 0 (0 points): no numbers exist
90 level 1 (5 points): one number exists
91 level 1 (7 points): 3 or more numbers exists
93 special characters:
94 level 0 (0 points): no special characters
95 level 1 (5 points): one special character exists
96 level 2 (10 points): more than one special character exists
98 combinatons:
99 level 0 (1 points): letters and numbers exist
100 level 1 (1 points): mixed case letters
101 level 1 (2 points): letters, numbers and special characters
102 exist
103 level 1 (2 points): mixed case letters, numbers and special
104 characters exist
107 ************************************************************ */
108 function testPasswordCss(passwd)
109 {
110 var description = new Array();
111 description[0] = "Minimum Strength Not Met";
112 description[1] = "Weak";
113 description[2] = "Improving";
114 description[3] = "Strong";
115 description[4] = "Strongest";
116 description[5] = "Begin Typing";
118 var intScore = 0
119 var strVerdict = 0
121 // PASSWORD LENGTH
122 if (passwd.length==0 || !passwd.length) // length 0
123 {
124 intScore = -1
125 }
126 else if (passwd.length>0 && passwd.length<5) // length between 1 and 4
127 {
128 intScore = (intScore+3)
129 }
130 else if (passwd.length>4 && passwd.length<8) // length between 5 and 7
131 {
132 intScore = (intScore+6)
133 }
134 else if (passwd.length>7 && passwd.length<12)// length between 8 and 15
135 {
136 intScore = (intScore+12)
137 }
138 else if (passwd.length>11) // length 16 or more
139 {
140 intScore = (intScore+18)
141 }
144 // LETTERS (Not exactly implemented as dictacted above because of my limited understanding of Regex)
145 if (passwd.match(/[a-z]/)) // [verified] at least one lower case letter
146 {
147 intScore = (intScore+1)
148 }
150 if (passwd.match(/[A-Z]/)) // [verified] at least one upper case letter
151 {
152 intScore = (intScore+5)
153 }
155 // NUMBERS
156 if (passwd.match(/\d+/)) // [verified] at least one number
157 {
158 intScore = (intScore+5)
159 }
161 if (passwd.match(/(.*[0-9].*[0-9].*[0-9])/)) // [verified] at least three numbers
162 {
163 intScore = (intScore+5)
164 }
167 // SPECIAL CHAR
168 if (passwd.match(/.[!,@,#,$,%,^,&,*,?,_,~]/)) // [verified] at least one special character
169 {
170 intScore = (intScore+5)
171 }
173 // [verified] at least two special characters
174 if (passwd.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/))
175 {
176 intScore = (intScore+5)
177 }
180 // COMBOS
181 if (passwd.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) // [verified] both upper and lower case
182 {
183 intScore = (intScore+2)
184 }
186 if (passwd.match(/([a-zA-Z])/) && passwd.match(/([0-9])/)) // [verified] both letters and numbers
187 {
188 intScore = (intScore+2)
189 }
191 // [verified] letters, numbers, and special characters
192 if (passwd.match(/([a-zA-Z0-9].*[!,@,#,$,%,^,&,*,?,_,~])|([!,@,#,$,%,^,&,*,?,_,~].*[a-zA-Z0-9])/))
193 {
194 intScore = (intScore+2)
195 }
198 //if you don't want to prevent submission of weak passwords you can comment out
199 // document.getElementById("formSubmit").disabled = true;
201 if(intScore == -1)
202 {
203 strVerdict = description[5];
204 document.getElementById("meterEmpty").style.width= "100%";
205 document.getElementById("meterFull").style.width= "0";
206 document.getElementById("formSubmit").disabled = true;
207 }
208 else if(intScore > -1 && intScore < 16)
209 {
210 strVerdict = description[0];
211 document.getElementById("meterEmpty").style.width= "100%";
212 document.getElementById("meterFull").style.width= "0%";
213 document.getElementById("formSubmit").disabled = true;
214 }
215 else if (intScore > 15 && intScore < 25)
216 {
217 strVerdict = description[1];
218 document.getElementById("meterEmpty").style.width= "100%";
219 document.getElementById("meterFull").style.width= "25%";
220 document.getElementById("formSubmit").disabled = false;
221 }
222 else if (intScore > 24 && intScore < 35)
223 {
224 strVerdict = description[2];
225 document.getElementById("meterEmpty").style.width= "100%";
226 document.getElementById("meterFull").style.width= "50%";
227 document.getElementById("formSubmit").disabled = false;
228 }
229 else if (intScore > 34 && intScore < 45)
230 {
231 strVerdict = description[3];
232 document.getElementById("meterEmpty").style.width= "100%";
233 document.getElementById("meterFull").style.width= "75%";
234 document.getElementById("formSubmit").disabled = false;
235 }
236 else
237 {
238 strVerdict = description[4];
239 document.getElementById("meterEmpty").style.width= "100%";
240 document.getElementById("meterFull").style.width= "100%";
241 document.getElementById("formSubmit").disabled = false;
242 }
244 //Changed by <pollmeier@gonicus.de>: no need for words
245 //document.getElementById("Words").innerHTML= (strVerdict);
247 }