Generate Random String of any Length

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

Post Reply
User avatar
JayBird
Admin
Posts: 4524
Joined: Wed Aug 13, 2003 7:02 am
Location: York, UK
Contact:

Generate Random String of any Length

Post by JayBird »

Code: Select all

<?

function str_makerand ($minlength, $maxlength, $useupper, $usespecial, $usenumbers) 
{ 
/* 

Description: string str_makerand(int $minlength, int $maxlength, bool $useupper, bool $usespecial, bool $usenumbers) 
returns a randomly generated string of length between $minlength and $maxlength inclusively. 

Notes: 
- If $useupper is true uppercase characters will be used; if false they will be excluded. 
- If $usespecial is true special characters will be used; if false they will be excluded. 
- If $usenumbers is true numerical characters will be used; if false they will be excluded. 
- If $minlength is equal to $maxlength a string of length $maxlength will be returned. 
- Not all special characters are included since they could cause parse errors with queries. 

Modify at will. 
*/ 
    $charset = "abcdefghijklmnopqrstuvwxyz"; 
    if ($useupper)   $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    if ($usenumbers) $charset .= "0123456789"; 
    if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";   // Note: using all special characters this reads: "~!@#$%^&*()_+`-={}|\\]?[":;'><,./"; 
    if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength); 
    else                         $length = mt_rand ($minlength, $maxlength); 
    for ($i=0; $i<$length; $i++) $key .= $charset[(mt_rand(0,(strlen($charset)-1)))]; 
    return $key; 
}

?>
Comments should explain everything nicely.

Mark
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

Hey B,

Just checked out your code. Some cool things in my opinion. Being able to use the special characters is awesome. Cool idea.

Here are some thoughts.

1) The variable length thing is kind of cool, but what would this be used for? If it's to generate random passwords, the longer the better right? If that's the use, I'd drop the overhead of finding out what size the returned string is going to be.

2) If I'm not mistaken, this....

Code: Select all

$charset = "abcdefghijklmnopqrstuvwxyz";
is a string, but this

Code: Select all

$key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
is referring to $charset as an array. So which is it? I added a couple of lines to the function to echo out the var type using gettype. It comes back string both times. Turn your error reporting all the way up and see what comes back. I got a feeling that PHP is covering for you somewhere in here. Either that, or there is something here that I don't know. Normally, $var[$number] is going to reference an element of an array. Not a position in a string. It's possible that PHP is figuring out what's needed. Especially when we remember that at the engine level (the php core), which is written in C, a string is actually an array of characters.

Now while PHP can do this for you, it's slower. You may have been better off to implement this using an array.

Consider me confused.

3) You may also want to consider curly braces and indentation. It would make the code more readable. Perhaps something like...

Code: Select all

if ($minlength > $maxlength) 
    { $length = mt_rand ($maxlength, $minlength); }

// or 

if ($minlength > $maxlength) { 
    $length = mt_rand ($maxlength, $minlength); 
}

// or

if ($minlength > $maxlength) 
    { 
    $length = mt_rand ($maxlength, $minlength); 
    }
Now I have a password generator that doesn't do the cool special characters, but it is capable of generating a passwd with a percentage of numbers based on weight. Here is how it works.

1) If the wieght is set to 26, then you will receive all upper case letters. Not good that one. You're just begging to get hacked with that! 8O

2) If you set it to 52, then it is capable of setting a 50/50 split of upper and lower case letters.

3) If you set it to 104, the you are likely to recieve a 50/50 split of characters and numbers.

4) If you set it to 208, you will most likely see twice as many numbers as characters.

Of course, you can use any number you want for the weight. Same goes for the length. You will also see that there are some default values as well.

Here it is...

Code: Select all

function gen_pass($pass_length='', $weight='')
	{
	$genned_pass='';											# Our string var
	!empty($pass_length) ? '' : $pass_length=25;				# First, set the lenght of the password
	!empty($weight) ? '' : $weight=104;							# Now let's set the weight
	
  	# Then also set the letter array
  	$letters=array(1=>'A', 2=>'B', 3=>'C', 4=>'D', 5=>'E', 6=>'F', 7=>'G', 8=>'H', 
		    9=>'I', 10=>'J', 11=>'K', 12=>'L', 13=>'M', 14=>'N', 15=>'O', 
		    16=>'P', 17=>'Q', 18=>'R', 19=>'S', 20=>'T', 21=>'U', 22=>'V', 
		    23=>'W', 24=>'X', 25=>'Y', 26=>'Z', 27=>'a', 28=>'b', 29=>'c', 30=>'d',
				31=>'e', 32=>'f', 33=>'g', 34=>'h', 35=>'i', 36=>'j', 37=>'k', 38=>'l', 
				39=>'m', 40=>'n', 41=>'o', 42=>'p', 43=>'q', 44=>'r', 45=>'s', 46=>'t', 
				47=>'u', 48=>'v', 49=>'w', 50=>'x', 51=>'y', 52=>'z');
    
  	# Now build the password string
  	for($x=0; $x<$pass_length; ++$x)
		{
		mt_srand(make_seed()); 
		$rand_out=mt_rand(1, $weight);
		if($rand_out>52)
			{ 
			$num=mt_rand(1, 9);
			settype($num, "string");
			$genned_pass.=$num; 
			}			
		else
			{ $genned_pass.=$letters[$rand_out]; }			
		}

	return $genned_pass;
	}

function make_seed() 
    { 
    list($usec, $sec) = explode(' ', microtime()); 
    return (float) $sec + ((float) $usec * 100000); 
    }
The make_seed() function is needed. I should just put those two lines inside the funcition. As a matter of fact, I think I will do that later.

One thing is certain, I'm prolly going to add some of those special characters to the array. I will most likely also create a second $weight var.

Tell me what you think.

Cheers,
BDKR
evilMind
Forum Contributor
Posts: 145
Joined: Fri Sep 19, 2003 10:09 am
Location: Earth

Post by evilMind »

see php man for [php_man]pack[/php_man]

Code: Select all

<?
//Generate a random string with special chars
function GenerateUniqueID( $length = 20 ) {
   $uniqueID = '';
   for ( $counter = 0; $counter < $length; $counter++ ) {
      $uniqueID .= pack('C' , rand( 48 , 122));
   }
   return($uniqueID);
}

//Generate a random string using only a-zA-Z
function GenerateUniqueID( $length = 20 ) {
   $charList = '';
   $uniqueID = '';

   for ( $preCount = 65 , $postCount = 97; $preCount < 91 && $postCount < 123; $preCount++, $postCount++ ) {
      $charList[] = pack('C' , $preCount);
      $charList[] = pack('C' , $postCount);
   }

   for ( $counter = 0; $counter < $length; $counter++ ) {
      $uniqueID .= $charList[rand(0 , (count($charList) - 1))];
   }

   return($uniqueID);
}
?>
Post Reply