2 * Password strength checker
4 * All scores are ranged approximately 0 (total disaster) - 100 (_looks_ great)
5 * @todo Check for popular passwords and keyboard sequences (QWERTY, etc)
8 // Estimates how hard it would be to pick the password using brute force
9 window
.bruteForceComplexity = function( pwd
) {
10 var score
= pwd
.length
* 5;
16 /[-_;:\.,'"`~!@#$%\^&\*\(\)\[\]\{\} ]/
20 for ( var i
=0; i
< regexes
.length
; i
++ ) {
21 if ( pwd
.match( regexes
[i
] ) ) {
26 var matches
= pwd
.match( /[\x80-\uFFFF]/g );
30 var s
= matches
.join( '' );
31 // poor man's isUpper() and isLower()
32 if ( s
!= s
.toLowerCase() && s
!= s
.toUpperCase() ) {
36 score
+= ( charClasses
- 1 ) * 10;
41 // Calculates a penalty to brute force score due to character repetition
42 window
.repetitionAdjustment = function( pwd
) {
44 for ( var i
=0; i
< pwd
.length
; i
++ ) {
45 if ( unique
.indexOf( pwd
[i
] ) < 0 ) {
49 var ratio
= pwd
.length
/ unique
.length
- 0.4; // allow up to 40% repetition, reward for less, penalize for more
54 // Checks how many simple sequences ("abc", "321") are there in the password
55 window
.sequenceScore = function( pwd
) {
56 pwd
= pwd
.concat( '\0' );
57 var score
= 100, sequence
= 1;
58 for ( var i
= 1; i
< pwd
.length
; i
++ ) {
59 if ( pwd
.charCodeAt( i
) == pwd
.charCodeAt(i
- 1) + 1 ) {
63 score
-= sequence
* 7;
68 for ( var i
= 1; i
< pwd
.length
; i
++ ) {
69 if ( pwd
.charCodeAt( i
) == pwd
.charCodeAt(i
- 1) - 1 ) {
73 score
-= Math
.sqrt( sequence
) * 15;
82 function passwordChanged() {
84 var pwd
= $( passwordSecurity
.password
).val();
86 $( '#password-strength' ).html( '' );
89 if ( pwd
.length
> 100 ) pwd
= pwd
.slice( 0, 100 );
91 bruteForceComplexity( pwd
),
92 repetitionAdjustment( pwd
),
96 var score
= Math
.min( scores
[0] - scores
[1], scores
[2] );
100 } else if ( score
< 60 ) {
102 } else if ( score
< 80 ) {
103 result
= 'acceptable';
105 var message
= '<span class="mw-password-' + result
+ '">' + passwordSecurity
.messages
['password-strength-' + result
]
107 $( '#password-strength' ).html(
108 passwordSecurity
.messages
['password-strength'].replace( '$1', message
)
113 function retypeChanged() {
114 var pwd
= $( passwordSecurity
.password
).val();
115 var retype
= $( passwordSecurity
.retype
).val();
117 if ( pwd
== '' || pwd
== retype
) {
119 } else if ( retype
== '' ) {
120 message
= passwordSecurity
.messages
['password-retype'];
122 message
= passwordSecurity
.messages
['password-retype-mismatch'];
124 $( '#password-retype' ).html( message
);
127 $( document
).ready( function() {
128 $( passwordSecurity
.password
).bind( 'keyup change', passwordChanged
);
129 $( passwordSecurity
.retype
).bind( 'keyup change', retypeChanged
);