PHP password generator

Simple password generator class in PHP. Allow users to choose what kind of characters should be in the password

After long and hectic day with office work in the night I relax to do some coding (by the way I spend 80% of my office time doing coding :P). So, I decided to write a “Create Password” utility. This is just for the sake of code something because there are many fancy libraries for this purpose already available, as open source rocks!!!

First I thought what password could have, alphabets small and capital, number and special character but user must have flexibility to exclude any of this option so I came up with a class having all options.

 

abstract class Options
{	
	const SmallAlphabets = 0;
	const CapitalAlphabets = 1;
	const IsNumeric = 2;	
	const IsSpecialCharacters = 3;
}

I made it abstract, as I did not need to implement any function inside the class. It worked as enumeration.

Then I created a function to allow user to enable what options he wants and set options in constructor as the set on the generation of class object. User can omit code to disable any option

 

function UseInPassword($options){
/** set correponding bit value to 1 to keep track of allowed options */
$this->optionsTrack = $this->optionsTrack | pow(2,$options);
}

Here, I did a trick, I played with logical operators and I set the bit in an integer corresponding the value any option had in Options class.

GetPassword is the main function. User called that from outside. I wanted to generate all characters equally. For example, password length is 6 and user enable only SmallAlphabets, then 6 small alphabets will be created but if SmallAlphabets and IsNumeric is enabled then 3 small alphabets and there number. What if user enables all? There are four options and length is 6. 6 is not divisible by 4 so we cannot generate all options equally. We have to take reminder to generate more characters equal to reminder to fulfill password length. So each option generated once to make 4 characters and code will generate 2 more character in the sequence of their values in Options class. As follow

Count the options set by user by checking corresponding bit

 

for($i = 0 ; $i < 5 ; $i++){			
			$mask = $this->optionsTrack & pow(2,$i);
			if($mask > 0){
				$optionsCount++;
				$allowedOptions .= strval($i);
			}
		}


Get count of characters per option

 

$initialOptionCount = intval($this->passwordLength / $optionsCount);	
$reminder = $this->passwordLength % $optionsCount;	

Get final count as if password length is not completely divisible by the count of allowed option then we have to generate some character one more time

 

$finalOptionsCount = $initialOptionCount + ($i < $reminder ? 1 : 0);

Complete commented code is below and on git Hub and easy to understand.

Complete PHP code for Password generator

 

<?php
// namespacess
namespace junaid\code\pword\generator;

/** enumeration class to define what password would have and what would not have */
abstract class Options
{	
	const SmallAlphabets = 0;
	const CapitalAlphabets = 1;
	const IsNumeric = 2;	
	const IsSpecialCharacters = 3;
}


/** passsword generator class */
class Generator{
	
	public $passwordLength;
	public $optionsTrack;	
	
	/** below you can update a list of special character 	 
	 	and add or remove characters according to your will */ 
	private $specialCharacters = [
			'~','`','!','@','#','$','%',
			'^','&','*','(',')','-',
			'_','=','<','>',
			';',':','[',']','{','}'
	];
	
	function __construct(){
		$this->passwordLength = 7;
		$this->UseInPassword(Options::SmallAlphabets);
		$this->UseInPassword(Options::CapitalAlphabets);
		$this->UseInPassword(Options::IsNumeric);
		$this->UseInPassword(Options::IsSpecialCharacters);
	}
	
	/** enable different type of characters by passing corresponding Options value
	 	See in constructor how I enable all options by four calls of this function */
	function UseInPassword($options){
		/** set correponding bit value to 1 to keep track of allowed options */
		$this->optionsTrack = $this->optionsTrack | pow(2,$options);
	}
	
	function GetPassword(){
		if(0 == $this->optionsTrack)
			exit("No parameter set....");
		$optionsCount = null;
		$allowedOptions = "";
		
		/** count what are the options set by user by ANDing corresponding bit value with power of 2 */
		for($i = 0 ; $i < 5 ; $i++){			
			$mask = $this->optionsTrack & pow(2,$i);
			if($mask > 0){
				$optionsCount++;
				$allowedOptions .= strval($i);
			}
		}
		
		/** get count of characters per option need to be created */
		$initialOptionCount = intval($this->passwordLength / $optionsCount);		
		$reminder = $this->passwordLength % $optionsCount;
		
		$passwordArray = array();

		/** generate characters and put in array */
		for($i = 0 ; $i < strlen($allowedOptions) ; $i++){
			/** if provided lenght is not divisble by the count of allowed options
			  	some options need to be created more than other to get no of character 
			  	equal to password length */			
			$finalOptionsCount = $initialOptionCount + ($i < $reminder ? 1 : 0);
			
			for($j = 0 ; $j < $finalOptionsCount ; $j++){
				$passwordArray[] = $this->GetSingleCharacter($allowedOptions[$i]);
			}
		}
		
		/** shuffle */
		shuffle($passwordArray);
				
		return implode($passwordArray);
	}
	
	/** return character on the basis of provided option value */
	function GetSingleCharacter($switch)
	{
		$tmp;
		switch($switch){
			case Options::CapitalAlphabets:
				$tmp = chr(rand(65,90));
			break;
			case Options::SmallAlphabets:
				$tmp = chr(rand(97,122));
			break;
			case Options::IsNumeric:
				$tmp = rand(0,9);
			break;
			case Options::IsSpecialCharacters:
				$tmp = $this->specialCharacters[rand(0,sizeof($this->specialCharacters)-1)];
			break;
		}		
		return $tmp;
	}
	
	function __desctruct(){
	}
}


use junaid\code\pword\generator as ns;
$obj = new ns\Generator;
echo $obj->GetPassword();

?>


Leave a comment