-
Two methods for generating random strings and passwords
Posted on April 14th, 2009 2 comments
Many websites and boards, upon registration, send the new users an e-mail with their user name and a random password. This is just one of the many purposes for which generating a random string or password is useful.Ever wondered how this is done? Actually, with PHP, it’s very easy. I will explain you two ways of doing so, and provide the necessary code for you to have the script up and running immediately; you may use the one which suits your needs most. Of course, those are not the only ways to achieve the same goal, but are very effective and in the same time, easy to understand. Note that in this post, the random string will be used as password.
Hash-based generator
This approach is perfect for low-strength or temporary passwords. The pros are: extremely lightweight and fast script, combines a range of lower case letters and numbers, and it can generate almost unique passwords every time it is run. The cons: limited length, rather weak passwords, and does not allow symbols, upper case characters, some lower case characters, etc.
The script code:
<?php function generatePassword($algorithm, $chars){ $pwd = $algorithm(microtime()); $pwd= substr($pwd, 0, $chars - 1); return $pwd; } echo generatePassword('md5','12'); ?>First of all, you have to decide which algorithm will be used to generate the hash. You can choose the PHP built-in algorithms (MD5, SHA1). Take into account that MD5 will generate a password of maximum 32 characters, whereas SHA1’s maximum length will be of 40 characters. If you set a greater length, it will be ignored. When a smaller length is chosen, only the first characters of the hash will be used as password.
What makes the passwords be almost certainly unique, without needing logs to exclude them from future generated passwords, is the microtime() function. When called, this PHP function returns the current timestamp. This means, that every time the script is run, the value returned will be different. Therefore, when this timestamp is hashed by the algorithm, it will always return a different hash. At this point it becomes logic to say, that the longer the generated password is, the lesser the possibilities of a password being not unique. At full length of the algorithm, it is almost impossible that two passwords generated from different timestamps are the same.
Random generator
If the algorithm method above is not sophisticated enough for your needs, or you need to generate strong passwords, you might find this script more convincing. Here, the password is not generated by hashing but by character-to-character construction of a random string. What are the pros? Well, it is highly customisable (allows you to include the characters you want into the character pool), allows an unlimited length (unless you use the “no repeat” mode), allows combination of upper and lower case characters and even inclusion of spaces, etc. therefore it can generate very strong passwords. The cons: more lines of code, a bit more difficult to understand (for beginners) and passwords are not necessarily unique (unless you use logs).
To use this script, you will have to configure its settings at first, in the first part of it.
Once configured, you can run it like in the code below.
<?php function generatePassword($chars){ //********************************* // // CONFIGURATION // //********************************* // Allowed random range (only relevant if length is 0 or empty) $minlength = '8'; $maxlength = '12'; // Type of characters allowed (0 = no, 1 = yes) $numeric = '1'; $uppercase = '1'; $lowercase = '1'; $symbols = '1'; $space = '0'; // Character set in each group $char_numeric = '0123456789'; $char_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $char_lowercase = 'abcdefghijklmnopqrstuvwxyz'; $char_symbols = '!#$%&()+&-_?/'; $char_space = ' '; // Allow an exact character more than once? // (0 = no, 1 = yes) $repeat = '1'; //********************************* // // PASSWORD GENERATOR // //********************************* // Put together possible chars $charset = ''; if($numeric == '1'){$charset .= $char_numeric;} if($uppercase == '1'){$charset .= $char_uppercase;} if($lowercase == '1'){$charset .= $char_lowercase;} if($symbols == '1'){$charset .= $char_symbols;} if($space == '1'){$charset .= $char_space;} // Randomise length if 0 if($chars == '0'){ $chars = mt_rand($minlength, $maxlength); } // Generate... $pwd = ''; $i = 0; while ($i < $chars) { $char = substr($charset, mt_rand(0, strlen($charset)-1), 1); // Handle repeated characters... if ($repeat == '0'){ if (!strstr($pwd, $char)) { $pwd .= $char; $i++; } } elseif ($repeat == '1') { $pwd .= $char; $i++; } } return $pwd; } echo generatePassword('0'); ?>How does it work? First of all, all the allowed characters from the character pool are concatenated into a same string. Secondly, it checks if the chosen length is ‘0′. In this case, it will generate a random length password, within the range you specify in the configuration of the script.
Once this is done, the script uses a while() loop to build the password one character at a time, by randomly selecting each time a random character from the variable containing all the available characters. This last part is done using the mt_rand() function.
Finally, still in the loop process, it checks if characters are being repeated or not (this is relevant if you chose the no repeat mode). If you don’t want characters to be repeated, each time the current character already exists in the string, it won’t be included but instead the script attempts to find a different character. Note that this is case sensitive.
Related posts:
2 responses to “Two methods for generating random strings and passwords”
-
I use the 1st one with the algorithm as it’s a lot more elegant. I would say that may be better to use microtime() as this would pretty much guarantee that no two hashes would be the same.
Also, if the database stores something like “sign up date” this could lead to the dissemination of passwords when using time(), if hacked into.
Good article though.
-
Good one Tom! I will modify the code with the change you suggest
Thanks for your feedback
Leave a reply
-


