Let me begin this post by saying that almost no event is truly random. Even the outcome of a classic coin toss could in theory be predicted if we knew the effect of every factor involved, like air friction, gravity, and initial force.
The same thing is applicable to the generation of random numbers and alphanumeric strings. The best we can hope for is to generate numbers and strings that don’t seem to follow a pattern and can’t be practically predicted by an attacker.
In this tutorial, we will cover different techniques for generating random numbers and alphanumeric strings in PHP. Some of them will be cryptographically secure, while others are meant only for casual use, like assigning pseudo-random file names or creating URLs and suggesting usernames.
Generating Random Numbers in PHP
There are three different functions for generating random numbers in PHP. All of them will accept a minimum and maximum possible value for the random numbers and output a random number for you. These are rand($min, $max)
, mt_rand($min, $max)
, and random_int($min, $max)
.
With rand()
, the minimum and maximum values of integers you can generate lie between 0
and the value returned by getrandmax()
. Before PHP 7.1.0, this function was about four times slower than mt_rand()
. However, starting from PHP 7.1.0, it has been made an alias of mt_rand()
. Unlike mt_rand()
, though, you can set the value of $max
to be lower than $min
without causing an error.
With mt_rand()
, the minimum and maximum values of integers you can generate lie between 0
and the value returned by mt_getrandmax()
. It relies on an implementation of the Mersenne Twister to generate random numbers. Watch out, though—prior to PHP 7.1.0, this function implemented an incorrect version of the algorithm to generate the numbers. However, it has been fixed in newer versions.
The function became even better in PHP 7.2.0 by getting rid of a modulo bias bug. This means that for some particular seeds, your sequence of random numbers will now be slightly better compared to older versions. Some specialized code might actually rely on this bias, though. If so, you can use the older seed algorithm by calling the mt_srand()
function to seed the random number generator and passing MT_RAND_PHP
as the value of the second parameter.
The mt_rand()
function has a period of 219937−1, which basically means that in best case scenarios you get as many as 219937−1 random numbers before the sequence starts repeating. You should note that repetition of a sequence is not the same as repetition of a particular number. In other words, you might get the same random number twice, but that does not mean that the sequence itself has started repeating. The following sequence is an example:
187 3276 1267 15 1267 34598 3467 125 17
In the above sequence, we had 1267 twice in the output, but that does not mean that the whole sequence started repeating after that. It’s unlikely to get the same number repeated so soon in a random sequence, but it is possible!
Cryptographically Secure Random Integers
If you want cryptographically secure pseudo-random numbers, the random_int()
function in PHP is your best bet. It will generate random numbers between the provided $min
and $max
values, which default to PHP_INT_MIN
and PHP_INT_MAX
. Unfortunately, this function is only available starting from PHP 7.0. For versions before that, you can use this polyfill on GitHub.
Random Floats
Instead of generating random integers, you might also want to generate floats. This can be done effortlessly by simply dividing a random number with a value returned by mt_getrandmax()
. The following example will illustrate how to generate a random float between 0 and 1 or between any other minimum and maximum limits.
When generating a random float between given limits, we make sure that the random integer numbers do not go above $max - 1
. This way, we can be sure that adding the float part will not take the number above the maximum limit.
Seeding the Random Number Generators
One concept that needs a little bit of explanation is seeds. Put simply, these are just numbers that can be used to initialize the rand()
and mt_rand()
functions before generating any random numbers. The function which seeds rand()
is called srand($seed)
, and the function which seeds mt_rand()
is called mt_srand($seed, $mode)
.
It’s important to remember that providing an initial seed value every single time before calling rand()
and mt_rand()
won’t necessarily produce better random numbers. In fact, using the same seed each time will give you the same random number as well!
Seeding a random number is useful in situations where you want to generate a random but reproducible sequence. The following code snippet generates the same sequence of random numbers when run twice.
Generating reproducible random sequences this way can help debug programs which were being tested using random data—if you keep track of the seed, you can reproduce the same input to figure out what went wrong.
Generating Random Alphanumeric Strings in PHP
There are many ways to generate random alphanumeric strings, and what you use will depend on your needs.
Generate Shuffled Strings
If you want to generate random alphanumeric strings from a fixed set of characters, you can use the
str_shuffle($string)
function. This function will provide you a randomly shuffled string. Starting from PHP 7.1, the algorithm which determines the random order of characters in the output string has been changed to the Mersenne Twister.Remember that the random string generated this way is not cryptographically secure. However, the string will still be pretty unpredictable for common use like generating random file names or URLs. Here are a few examples:
Your output will most probably be different in both cases. In the first case, we just shuffled the permitted characters string and then took the first 10 characters of it. In the second case, we added "video" at the beginning of the generated string and ".mp4" at the end.
This method of generating random alphanumeric strings is very easy, but it has a couple of issues. For example, you will never get the same characters in your random string twice. Also, the length of the random output string can only be as long as the input string.
Generate Random Strings
If the problems I listed above are a deal breaker, you might want to look at some other implementations. The following code will solve both these problems.
You can modify it to add particular suffixes and prefixes to the generated random string. People who are using PHP 7 can improve the string generation further by using the cryptographically secure function
random_int()
instead ofmt_rand()
.Generate Random Hexadecimal Strings
If you want to generate random hexadecimal strings in PHP, you can also use either the
md5($string, $raw_output)
or thesha1($string, $raw_output)
function. Both of them will generate hashes of a given input string.You will keep getting unique hashes as long as the input is unique. This could be achieved by using the output of a function like
time()
as the input. By default,md5()
will return a 32-character hexadecimal string, andsha1()
will return a 40-character hexadecimal string. These can be trimmed to a specific length using thesubstr()
function.Here is an example of the output returned by these functions:
As you can see, generating random and unique hexadecimal strings up to 40 characters long is very easy in PHP.
Generate Cryptographically Secure Random Strings
The three functions to generate random alphanumeric strings that we have discussed so far are not cryptographically secure. Luckily, PHP also has a function called
random_bytes($length)
to generate cryptographically secure pseudo-random bytes. The$length
parameter determines how long the output string should be.Once you have the output in terms of random bytes, you can use the
bin2hex()
function to convert them to hexadecimal values. This will double the length of the string.Another function that you can use to generate cryptographically secure random bytes is
openssl_random_pseudo_bytes($length, &$crypto_strong)
. The value of the second parameter can be used to determine if the output string will be generated using a cryptographically secure algorithm or not.Final Thoughts
In this tutorial, we looked at the generation of random numbers and alphanumeric strings in PHP. Generating random numbers can be useful in a variety of situations, like in games where you have to spawn enemy players or randomly give users some clues about letters so they can form a whole word.
Just like random numbers, the generation of random alphanumeric strings can also be pretty helpful in many circumstances. With the help of
str_shuffle()
, you can choose which set of characters appear in your random strings. Withsha1()
andmd5()
, you can easily generate random hexadecimal sequences, and withrandom_bytes()
you can generate cryptographically secure strings. This will allow you to generate meaningful yet randomized filenames and usernames that are hard to guess.I hope you enjoyed this tutorial. If you have any questions, feel free to ask them in the comments.
Powered by WPeMatico