What is the difference between the functions Rand, mt_rand, random_int?

Asked

Viewed 141 times

8

To generate random numbers with PHP, there are some functions. Among them rand, and mt_rand.

Until recently, I used the mt_rand, 'cause as the documentation says, she’s a "improved random number generator". For example, I used this function in reply.

However, PHP 7 now also has a function called random_int, that according to the documentation:

[...] Generates cryptographically Secure pseudo-Andom integers.

Faced with so many random number generation options, I would then like to know the following:

  • What are the main differences between these functions?
  • In the case of mt_rand, why it is considered a "improved random number generator"?
  • And the function random_int? She has some improvement over the others?
  • In which case should use each of them?

2 answers

7

I do not understand in depth, but what I am going to say is not wrong, so it may yield a few points. : D

Summary: use the random_int for anything involving information security (such as protected data transmission and storage) and leave to use the mt_rand (preferably because it is the fastest) or the rand (if performance is not an issue in your case) for all other cases where security/privacy are not concerns.

For anything related to encryption and information security, encrypt, decrypt, generate hashes, generate Salts, one should always use an "cryptographically secure" generator, even if in general these are the slowest. That’s because if it doesn’t have that characteristic the malicious ones who are in possession of some samples (samples) of data generated from it can statistically predict the numbers most likely to be generated and are more likely to render their safety unusable. So for these cases always use this random_int or better, should it arise in the future.

That one mt_rand as I understand it had an improvement over others but it was more on the issue of performance, using the "Mersenne Twister", so it is considered "improved". Even though it is faster than the ones used before, this generator is not yet considered cryptographically secure, as the linked documentation says, so avoid using it in cryptographic situations. Use it to generate mega-sena numbers, dice moves, which card to take out of the deck, these most trivial things.

And finally the rand It’s the worst of all, it’s not cryptographically secure, and it might not be performatic, either. But for trivial situations I think this shouldn’t be too impactful.

Finally there is the question that it is essential that the cryptographically safe generator is well "sown" when it is initialized (the "seed" or "Seed" is the initial value on which the generator is based to start generating other values). Otherwise, it is possible to predict what will be generated even without the need of previous samples, since the generator algorithm, however good it is in general, does not escape being pseudo-random and deterministic (real randomness depends on equipment which people do not normally have in ordinary computers). If the library already provides this "sowing" for you safely, great, otherwise you may have to find out how to arrange in hand.

5


rand and mt_rand, according to the documentation (here and here), are not considered cryptographically secure (for this purpose, the use of random_int, about which we will speak below).

So much rand how much mt_rand work in a similar way: if they are called without parameters, they return a number between zero and a maximum limit (for rand, the limit is the number returned by getrandmax, and to mt_rand, the limit is the number returned by mt_getrandmax).

If they are called with only one parameter, they both give one Warning ("expects Exactly 2 Parameters, 1 Given" <- tested in PHP 7.3.6) and return NULL.

If they are called with 2 parameters (called $min and $max), return a number between $min and $max, remembering that both are included (in many languages the final value is not included, so this is a factor that usually generates many off-by-one errors).

One "interesting" detail is that if $min is greater than $max, rand works, but mt_rand no. That is to say, rand(5, 3) returns a number between 3 and 5, but mt_rand(5, 3) gives a Warning ("max(3) is smaller than min(5)") and returns FALSE.

This happened in PHP 7.3.6 (version I used to test), even though the documentation said that from PHP 7.1 onwards rand became a alias of mt_rand. This behavior is mentioned in documentation of rand:

Note: As of PHP 7.1.0, rand() uses the same Random number Generator as mt_rand(). To preserve Backwards Compatibility rand() Allows max to be smaller than min as opposed to returning false as mt_rand().

In fact, in the above section we have another detail: from PHP 7.1 both use the same algorithm, which in this case is the Mersenne Twister (before that, rand wore the Linear Congruential Generator).


Already random_int has more differences. A documentation cites that it is a cryptographically secure function (and the trade-off is it be slower), and in addition it should always be called with 2 arguments, indicating the minimum and maximum values. Another difference to rand and mt_rand is that if the maximum is less than the minimum, a Error.

This function launches a Exception if no source of randomness appropriate. According to the documentation, this source varies according to the environment:

  • in Windows, for PHP >= 7.2.0 the CNG-API, for other versions is used CryptGenRandom
  • on Linux, the syscall getrandom(2), if available
  • on other platforms, use /dev/urandom
  • if none of these are found, launches a Exception

About "being cryptographically secure", see more details here and here. But basically, if you’re not dealing with encryption (for example, if you just want to change the background color of your website randomly), wouldn’t need to use random_int.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.