// Java Document

// Password strength meter v1.0
// Matthew R. Miller - 2007
// www.codeandcoffee.com
// Based off of code from  http://www.intelligent-web.co.uk

// Settings
// -- Toggle to true or false, if you want to change what is checked in the password
var bCheckNumbers = true;
var bCheckUpperCase = true;
var bCheckLowerCase = true;
var bCheckPunctuation = true;
var nPasswordLifetime = 365;

// Check password
function checkPassword(strPassword)
{
	// Reset combination count
	nCombinations = 0;
	
	// Check numbers
	if (bCheckNumbers)
	{
		strCheck = "0123456789";
		if (doesContain(strPassword, strCheck) > 0) 
		{ 
        		nCombinations += strCheck.length; 
    		}
	}
	
	// Check upper case
	if (bCheckUpperCase)
	{
		strCheck = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		if (doesContain(strPassword, strCheck) > 0) 
		{ 
        		nCombinations += strCheck.length; 
    		}
	}
	
	// Check lower case
	if (bCheckLowerCase)
	{
		strCheck = "abcdefghijklmnopqrstuvwxyz";
		if (doesContain(strPassword, strCheck) > 0) 
		{ 
        		nCombinations += strCheck.length; 
    		}
	}
	
	// Check punctuation
	if (bCheckPunctuation)
	{
		strCheck = ";:-_=+\|//?^&!.@$£#*()%~<>{}[]";
		if (doesContain(strPassword, strCheck) > 0) 
		{ 
        		nCombinations += strCheck.length; 
    		}
	}
	
	// Calculate
	// -- 500 tries per second => minutes 
    	var nDays = ((Math.pow(nCombinations, strPassword.length) / 500) / 2) / 86400;
 
	// Number of days out of password lifetime setting
	var nPerc = nDays / nPasswordLifetime;
	
	return nPerc;
}
 
 
 
 
 
 
 
// Runs password through check and then updates GUI 
function runPassword(strPassword, strFieldID) 
{
	//alert(strPassword);

	// Check password
	nPerc = checkPassword(strPassword);
	
	 // Get controls
    	var ctlBar = document.getElementById(strFieldID + "_bar"); 
    	var ctlText = document.getElementById(strFieldID + "_text");
    	if (!ctlBar || !ctlText)
    		return;
    	
    	// Set new width
    	var nRound = Math.round(nPerc * 100);
	if (nRound < (strPassword.length * 5)) 
	{ 
		nRound += strPassword.length * 5; 
	}
	if (nRound > 100)
		nRound = 100;
    	ctlBar.style.width = nRound + "%";
 
 	// Color and text
 	if (nRound > 75)
 	{
 		strText = "Very Secure";
 		strColor = "#3bce08";
 	}
 	else if (nRound > 50)
 	{
 		strText = "Secure";
 		strColor = "orange";
	}
 	else if (nRound > 25)
 	{
 		strText = "Mediocre";
 		strColor = "#ffd801";
 	}
 	else
 	{
 		strColor = "red";
 		strText = "Insecure";
 	}
	ctlBar.style.backgroundColor = strColor;
	ctlText.innerHTML = "<span style='color: " + strColor + ";'>" + strText + "</span>";
}
 
 
 
 
 
 function runAffPassword(strPassword, strFieldID) 
{
	//alert(strPassword);
	
	// Check password
	nPerc = checkPassword(strPassword);
	
	 // Get controls
    	var ctlBar = document.getElementById(strFieldID + "_bar"); 
    	var ctlText = document.getElementById(strFieldID + "_text");
    	if (!ctlBar || !ctlText)
    		return;
    	
    	// Set new width
    	var nRound = Math.round(nPerc * 100);
	if (nRound < (strPassword.length * 5)) 
	{ 
		nRound += strPassword.length * 5; 
	}
	if (nRound > 100)
		nRound = 100;
    	ctlBar.style.width = nRound + "%";
 
 	// Color and text
 	if (nRound > 75)
 	{
 		strText = "Very Secure";
 		strColor = "#3bce08";
 	}
 	else if (nRound > 50)
 	{
 		strText = "Secure";
 		strColor = "orange";
	}
 	else if (nRound > 25)
 	{
 		strText = "Mediocre";
 		strColor = "#ffd801";
 	}
 	else
 	{
 		strColor = "red";
 		strText = "Insecure";
 	}
	ctlBar.style.backgroundColor = strColor;
	ctlText.innerHTML = "<span style='color: " + strColor + ";'>" + strText + "</span>";
}
 
 
  function runAgentPassword(strPassword, strFieldID) 
{
	//alert(strPassword);
	
	// Check password
	nPerc = checkPassword(strPassword);
	
	 // Get controls
    	var ctlBar = document.getElementById(strFieldID + "_bar"); 
    	var ctlText = document.getElementById(strFieldID + "_text");
    	if (!ctlBar || !ctlText)
    		return;
    	
    	// Set new width
    	var nRound = Math.round(nPerc * 100);
	if (nRound < (strPassword.length * 5)) 
	{ 
		nRound += strPassword.length * 5; 
	}
	if (nRound > 100)
		nRound = 100;
    	ctlBar.style.width = nRound + "%";
 
 	// Color and text
 	if (nRound > 75)
 	{
 		strText = "Very Secure";
 		strColor = "#3bce08";
 	}
 	else if (nRound > 50)
 	{
 		strText = "Secure";
 		strColor = "orange";
	}
 	else if (nRound > 25)
 	{
 		strText = "Mediocre";
 		strColor = "#ffd801";
 	}
 	else
 	{
 		strColor = "red";
 		strText = "Insecure";
 	}
	ctlBar.style.backgroundColor = strColor;
	ctlText.innerHTML = "<span style='color: " + strColor + ";'>" + strText + "</span>";
}
 
 
 
 
 
 
 
 
// Checks a string for a list of characters
function doesContain(strPassword, strCheck)
 {
    	nCount = 0; 
 
	for (i = 0; i < strPassword.length; i++) 
	{
		if (strCheck.indexOf(strPassword.charAt(i)) > -1) 
		{ 
	        	nCount++; 
		} 
	} 
 
	return nCount; 
} 
 
 
 
 
 // password strength
	function RatePassword(pwd) {
		var strength  = GetPasswordStrength(pwd);
		var strengthPercent = ConvertToPercent(strength);
		document.getElementById("strengthdisplay").innerHTML = GetPasswordStrengthText(strengthPercent);
		var bardisplayGood = document.getElementById("bardisplayGood");
		var bardisplayBad = document.getElementById("bardisplayBad");
		var maxwidth = document.getElementById("bardisplayTable").width;
		var widthGood = 0;
		var widthBad = maxwidth;
		if (strengthPercent >= 80) {
			// anything above 80% is displayed as 100% good
			widthGood = maxwidth;
			widthBad = 0;
		} else if (strengthPercent >=0 && strengthPercent < 100) {
			// between zero and 100 display the ratio
			widthGood = (maxwidth * strengthPercent) / 100;
			widthBad = maxwidth - widthGood;
		}
		bardisplayGood.style.width = widthGood;
		bardisplayBad.style.width = widthBad;
	}
	
      function GetPasswordStrength(pwd) {
            // zero-length passwords cannot be rated
            if (pwd.length == 0) {
                  return -1;
            }
            // passwords that are too short are zero-strong
            if (pwd.length < 6) {
                  return 0;
            }
            var charsSpecial = "";
            var charsLowercase = "";
            var charsUppercase = "";
            var charsNumeric = "";
            var rating = 0;
            var bonus = 0;
            var i;
            
            // characters that follow each other in the alphabet are bad
            var charcode = pwd.charCodeAt(0); 
            for (i=1; i<pwd.length; i++) {
                  var diff = pwd.charCodeAt(i) - charcode;
                  charcode = pwd.charCodeAt(i);
                  if (diff == 1 || diff == -1) {
                        pwd = pwd.substring(0, i) + pwd.substring(i-1, i) + pwd.substring(i+1, pwd.length);
                  }
            }
            
            // put password characters into the right buckets
            for (i=0; i<pwd.length; i++) {
                  if (pwd.charCodeAt(i) >= 'a'.charCodeAt(0) && pwd.charCodeAt(i) <='z'.charCodeAt(0)) {
                        charsLowercase += pwd.substring(i, i+1);
                  } else if (pwd.charCodeAt(i) >= 'A'.charCodeAt(0) && pwd.charCodeAt(i) <='Z'.charCodeAt(0)) {
                        charsUppercase += pwd.substring(i, i+1);
                  } else if (pwd.charCodeAt(i) >= '0'.charCodeAt(0) && pwd.charCodeAt(i) <='9'.charCodeAt(0)) {
                        charsNumeric += pwd.substring(i, i+1);
                  } else {
                        charsSpecial += pwd.substring(i, i+1);
                  }
            }
                        
            rating = GetDistribution(charsLowercase);
            rating += GetDistribution(charsUppercase);
            rating += GetDistribution(charsNumeric);
            rating += GetDistribution(charsSpecial);
            
            if (charsLowercase.length > 0) bonus++;
            if (charsUppercase.length > 0) bonus++;
            if (charsNumeric.length > 0) bonus++;
            if (charsSpecial.length > 0) bonus++;
            
            rating = rating * (1 + ((bonus-1) / 4));
            return rating;
      }

	function ConvertToPercent(strength) {
		return 6*strength;
	}
		
	function GetDistribution(str) {
		var distribution = 0;
		var uniques = "";
		var i;
		for (i=0; i < str.length; i++) {
			if (uniques.indexOf(str.substring(i, i+1)) == -1) {
				uniques += str.substring(i, i+1);
			}
		}
		return uniques.length + ((str.length - uniques.length) / 5);
	}
	
	function GetPasswordStrengthText(strength) {
		if (strength == 0) {
			return "Too Short";
		} else if (strength > 0 && strength < 20) {
			return "Very Weak";
		} else if (strength >= 20 && strength < 40) {
			return "Fair";
		} else if (strength >= 40 && strength < 60) {
			return "Good";
		} else if (strength >= 60 && strength < 80) {
			return "Strong";
		} else if (strength >= 80) {
			return "Very Strong";
		} else {
			return "None";
		}
	}


