Javascript Password Strength Meter, Passwortstärke

Passwort:


Erlaubte Zeichen

	A-Z
	a-z
	0-9
	+-=¦|~!@#$%&*_
	

Style

	#strength {
		color:#333;
		font-family:Tahoma, Arial, Verdana, Helvetica, normal, sans-serif;
		font-style: normal;	
		font-size:0.8em;
		background-image: url(bg_strength_gradient.jpg);
		background-repeat: no-repeat;
		background-position: 0 0;
		width: 100px;
		z-index: 0;
		border:1px solid gray;
		display:none;
		height:16px;
		text-align:center;
	}
	.pos{
		position:absolute;
		left:45%;
		top:10%;
	}
	

Javascript

		function Password(arg_password, arg_spc_chars){
		    var actPassword = arg_password;
		    var spc_chars = arg_spc_chars;
		    this.lcase_count = 0;
		    this.ucase_count = 0;
		    this.num_count = 0;
		    this.schar_count = 0;
		    this.length = 0;
		    this.strength = 0;
		    this.runs_score = 0;
		    this.verdict = '';
		
		    // These numbers are just guesses on my part (and not
		    // all that educated, either ;) Adjust accordingly.
		    var verdict_conv = {'veryweak':2, 'weak':5, 'medium':53, 'strong':150, 'verystrong':250};
		
		    // These are weighting factors.  I figure that including
		    // numbers is a little better than including uppercase
		    // because numbers probably are not vulnerable to
		    // dictionary searches, and including special chars is
		    // even better.  These factors provide yet another
		    // dimension.  Again, there are only guesses.
		    var flc = 1.0;  // lowercase factor
		    var fuc = 1.0;  // uppercase factor
		    var fnm = 1.3;  // number factor
		    var fsc = 1.5;  // special char factor
		
		    this.getPwStrength = function(){
		        if ((this.run_score = this.detectPwRuns()) <= 1){
		        	this.strength = 1;
		        }else{
			        var regex_sc = new RegExp('['+spc_chars+']', 'g');
		
			        this.lcase_count = actPassword.match(/[a-z]/g);
			        this.lcase_count = (this.lcase_count) ? this.lcase_count.length : 0;
			        this.ucase_count = actPassword.match(/[A-Z]/g);
			        this.ucase_count = (this.ucase_count) ? this.ucase_count.length : 0;
			        this.num_count   = actPassword.match(/[0-9]/g);
			        this.num_count   = (this.num_count) ? this.num_count.length : 0;
			        this.schar_count = actPassword.match(regex_sc);
			        this.schar_count = (this.schar_count) ? this.schar_count.length : 0;
			        this.length = actPassword.length;
		
			        var avg = this.length / 4;
		
			        // I'm dividing by (avg + 1) to linearize the strength a bit.
			        // To get a result that ranges from 0 to 1, divide 
			        // by Math.pow(avg + 1, 4)
			        this.strength = ((this.lcase_count * flc + 1) * 
			                         (this.ucase_count * fuc + 1) *
			                         (this.num_count * fnm + 1) * 
			                         (this.schar_count * fsc + 1)) / (avg + 1);
		        }
				
		        if (this.strength > verdict_conv.verystrong){
		            this.verdict = 'Very Strong ';
		        }else if (this.strength > verdict_conv.strong){
		            this.verdict = 'Strong ';
		        }else if (this.strength > verdict_conv.medium){
		            this.verdict = 'Medium ';
		        }else if (this.strength > verdict_conv.weak){
		            this.verdict = 'Weak';
		        }else if (this.strength > verdict_conv.veryweak){
		            this.verdict = 'Very Weak';
		        }else{
		            this.verdict = "Forget it!";
		        }	
		
		        this.strength =  this.strength > verdict_conv.verystrong ? verdict_conv.verystrong : this.strength;
		        var percent = this.getPwPercent();
		        	percent < 0 ? 0 : percent;
		        this.verdict = this.verdict + " " + percent + "%";
		        document.getElementById('strength').style.backgroundPosition = "-" + parseInt(Math.round( (400 / verdict_conv.verystrong) * this.strength )) + "px";
				
		        return this.verdict;
		    };
		    
		    this.getPwPercent = function(){
		        return this.strength <= 2 ? 0 : Math.floor( (this.strength/verdict_conv.verystrong) * 100 ) - 1;
		    };
		    
		    // This is basically an edge detector with a 'rectified' (or
		    // absolute zero) result.  The difference of adjacent equivalent 
		    // char values is zero.  The greater the difference, the higher
		    // the result.  'aaaaa' sums to 0. 'abcde' sums to 1.  'acegi'
		    // sums to 2, etc.  'aaazz', which has a sharp edge, sums to  
		    // 6.25.  Any thing 1 or below is a run, and should be considered
		    // weak.
		    this.detectPwRuns = function(){	
		        var pwParts = actPassword.split('');
		        var ords = new Array();
		        for (i in pwParts)
		        {
		            ords[i] = pwParts[i].charCodeAt(0);
		        }
		
		        var accum = 0;
		        var lasti = ords.length-1;
		
		        for (var i=0; i < lasti; ++i){
		            accum += Math.abs(ords[i] - ords[i+1]);
		        }
		
		        return accum/lasti;
		    };
		}
		
		function checkPassword(){
			var special_chars = "+-=¦|~!@#$%&*_"; 
			var pw = new Password(document.getElementById('pw').value, special_chars); 
			var verdict = pw.getPwStrength();
			var strength = document.getElementById("strength");
			strength.style.display = "block";
			strength.innerHTML = verdict;
			return pw.getPwPercent();
		}	
	
	

HTML

	<input id="pw" style="width: 200px;" onkeyup="checkPassword()" type="password" />
<div id='strength'></div>

Image

	http://blog.myknow/Spielplatz/bg_strength_gradient.jpg