How to create a random string using PHP?
So, let me start off by saying USE A LIBRARY. Many exist:
- RandomCompat
- RandomLib
- SecurityMultiTool
The core of the problem is almost every answer in this page is susceptible to attack. mt_rand()
, rand()
, lcg_value()
and uniqid()
are all vulnerable to attack.
A good system will use /dev/urandom
from the filesystem, or mcrypt_create_iv()
(with MCRYPT_DEV_URANDOM
) or openssl_pseudo_random_bytes()
. Which all of the above do. PHP 7 will come with two new functions random_bytes($len)
and random_int($min, $max)
that are also safe.
Be aware that most of those functions (except random_int()
) return "raw strings" meaning they can contain any ASCII character from 0 - 255
. If you want a printable string, I'd suggest running the result through base64_encode()
.
Well, you didn't clarify all the questions I asked in my comment, but I'll assume that you want a function that can take a string of "possible" characters and a length of string to return. Commented thoroughly as requested, using more variables than I would normally, for clarity:
function get_random_string($valid_chars, $length)
{
// start with an empty random string
$random_string = "";
// count the number of chars in the valid chars string so we know how many choices we have
$num_valid_chars = strlen($valid_chars);
// repeat the steps until we've created a string of the right length
for ($i = 0; $i < $length; $i++)
{
// pick a random number from 1 up to the number of valid chars
$random_pick = mt_rand(1, $num_valid_chars);
// take the random character out of the string of valid chars
// subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
$random_char = $valid_chars[$random_pick-1];
// add the randomly-chosen char onto the end of our string so far
$random_string .= $random_char;
}
// return our finished random string
return $random_string;
}
To call this function with your example data, you'd call it something like:
$original_string = 'abcdefghi';
$random_string = get_random_string($original_string, 6);
Note that this function doesn't check for uniqueness in the valid chars passed to it. For example, if you called it with a valid chars string of 'AAAB'
, it would be three times more likely to choose an A for each letter as a B. That could be considered a bug or a feature, depending on your needs.
If you want to allow repetitive occurences of characters, you can use this function:
function randString($length, $charset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
{
$str = '';
$count = strlen($charset);
while ($length--) {
$str .= $charset[mt_rand(0, $count-1)];
}
return $str;
}
The basic algorithm is to generate <length> times a random number between 0 and <number of characters> â 1 we use as index to pick a character from our set and concatenate those characters. The 0 and <number of characters> â 1 bounds represent the bounds of the $charset
string as the first character is addressed with $charset[0]
and the last with $charset[count($charset) - 1]
.
My favorite:
echo substr(md5(rand()), 0, 7);