[ACCEPTED]-Generate cryptographically secure random numbers in php-random

Accepted answer
Score: 33

Pseudorandom number generators (PRNG) are very complex beast.

There are 36 no real "perfect" random number 35 generators -- in fact the best that can 34 be done from mathematical functions are 33 pseudorandom -- they seem random enough 32 for most intents and purposes.

In fact, performing 31 any additional actions from a number returned 30 by a PRNG doesn't really increase its randomness, and 29 in fact, the number can become less random.

So, my 28 best advice is, don't mess around with values 27 returned from a PRNG. Use a PRNG that is 26 good enough for the intended use, and if 25 it isn't, then find a PRNG that can produce 24 better results, if necessary.

And frankly, it 23 appears that the mt_rand function uses the Mersenne twister, which 22 is a pretty good PRNG as it is, so it's 21 probably going to be good enough for most 20 casual use.

However, Mersenne Twister is not designed to be used in any security contexts. See this answer for a solution 19 to use when you need randomness to ensure 18 security.


There was a question in the comments 17 why performing operations on a random number 16 can make it less random. For example, some 15 PRNGs can return more consistent, less random 14 numbers in different parts of the bits -- the 13 high-end can be more random than the low-end.

Therefore, in 12 operations where the high-end is discarded, and 11 the low end is returned, the value can become 10 less random than the original value returned 9 from the PRNG.

I can't find a good explanation 8 at the moment, but I based that from the 7 Java documentation for the Random.nextInt(int) method, which 6 is designed to create a fairly random value 5 in a specified range. That method takes 4 into account the difference in randomness 3 of the parts of the value, so it can return 2 a better random number compared to more 1 naive implementations such as rand() % range.

Score: 28

Quick answer:

In a new PHP7 there is a finally a support 33 for a cryptographically secure pseudo-random integers.

int random_int ( int $min , int $max )

There is also a polyfill for PHP5x.

Longer answer

There is no perfect 32 random number generator, and computers use 31 pseudorandom number generator to create sequences that looks random. The 30 sequences look random (and pass some randomness tests) but 29 because there is some algorithm to generate 28 it, you can repeat algorithm with absolutely 27 the same states and get the same result.

The 26 same advice as with cryptography "do not invent 25 your own cypher" can be translated 24 to random number generators and mean that 23 you can not just get a lot of random number 22 generators combined together and get expect 21 to get a better generator.

One of the subsets 20 of random number generators is cryptographically secure random number generators:

The requirements 19 of an ordinary PRNG are also satisfied by 18 a cryptographically secure PRNG, but the 17 reverse is not true. CSPRNG requirements 16 fall into two groups: first, that they pass 15 statistical randomness tests; and secondly, that 14 they hold up well under serious attack, even 13 when part of their initial or running state 12 becomes available to an attacker

So this 11 is pretty close to your definition of "perfect". One 10 more time under no condition (except of 9 learning how to do cryptography) you should 8 try to implement one of that algorithms 7 and use it in your system.

But luckily PHP7 has 6 it implemented,

int random_int ( int $min , int $max )

Generates cryptographic 5 random integers that are suitable for use where 4 unbiased results are critical (i.e. shuffling 3 a Poker deck).

The sources of random are 2 as follows:

  • On Windows CryptGenRandom() is used exclusively
  • arc4random_buf() is used if it is available (generally BSD specific)
  • /dev/arandom is used where available
  • The getrandom(2) syscall (on newer Linux kernels)
  • /dev/urandom is used where none of the above is available

This makes all the previous answers 1 obsolete (and some deprecated).

Score: 17

I'm not sure that what you've done "improves" the 8 randomness. From what I can understand 7 you generate 100 random numbers and then 6 randomly pick one of them.

From what I can 5 remember from my probability course, this 4 probably doesn't increase the randomness, as 3 if there is an underlying bias in the generator 2 function (mt_rand()), then it will still 1 be reflected somehow in the output.

Score: 14

In what way is mt_rand() "bad"?

For example: If 6 it favors a certain number. Lets say mt_rand(1, 10) favours 5 low numbers in the range, ie "1" and "2" occurs 4 on average more than 10% each. Then your 3 "improvement" would still suffer from the 2 same problem.

Selecting a random number out 1 of a faulty sequence will still be faulty.

Score: 12
  function random_number(){
      return 4; // return generated number
                // guaranteed to be random

All joking aside, you're getting into a 22 philosophical question of what is "random" or 21 what is "best". Ideally you'd 20 want your random numbers to have few patterns 19 in them over the course of your procedure. Generally 18 system time is used as the seed, but I've 17 also used the previous random number as 16 the seed, the previous random numberth ago 15 as the seed. The problem is, with a powerful 14 enough computer and full knowledge of the 13 hardware running, and generator function, you 12 would be able to predict the entire set 11 of numbers generated. Thus if you had a 10 powerful enough computer (some people put 9 God into this category) that knew all possible 8 variables and functions of the universe 7 you would then be able to predict every 6 event that happened or will happen. Most 5 random number generators are fine on their 4 own but if you know someone who can see 3 the patterns, more likely they are like 2 the guy in Beautiful Mind and you should 1 get them checked into a clinic.

By popular demand :D

Score: 5

I wrote a cronjob that gets 1000 numbers 7 from random.org periodically (say, once 6 an hour) and added them into a PHP array. Whenever 5 I want random numbers in my script, I use 4 mt_rand(0,1000) to call a number from that. A 3 few extra microseconds of overhead, but 2 I get truly random numbers based on natural 1 atmospheric noise.

Score: 2

It all depends what for you need that random 1 number :) For me ShuffleBag is the best one :)

Score: 2

Edit: My comment is no longer valid. Please 8 see the following answer: https://stackoverflow.com/a/31443898/109561

I'm guessing you're 7 worried about the distribution of mt_rand(). I 6 have tested it and it is very level and 5 both bounds are inclusive.

I added my test 4 to the comments of the documentation for 3 mt_rand() on the php manual, but it was 2 removed by a silly moderator due to politics 1 that are too long winded to go into here.

Score: 1

There is no such thing as a "perfect" random 10 number. No matter what subjective definition 9 of "perfect" you have. You can only achieve 8 pseudo-random.

I was simply trying to point 7 you in the right direction. You asked a 6 question about perfect random numbers, even 5 if perfect was in quotes. And yes, you 4 can improve randomness. You can even implement 3 heuristic or "natural" algorithms, such 2 ideas like "atmospheric noise" -- but still, you're 1 not perfect, not by any means.

Score: 1

If you don't like PHP's built in rand(), you probably 4 shouldn't use their built-in shuffle() either, since 3 it seems to be built on their rand().

I am halfway 2 sure the "industry standard" shuffle 1 now is the Fisher-Yates shuffle.

Score: 1

use /dev/ramdom (linux device true random 1 number generator) to seed mt_rand

$rnd_dev=mcrypt_create_iv(4, MCRYPT_DEV_RANDOM); //need "apt-get install php5-mcrypt"
$seed=ord(substr($rnd_dev, 0, 1))<<24 |
      ord(substr($rnd_dev, 1, 1))<<16 |
      ord(substr($rnd_dev, 2, 1))<<8 |
      ord(substr($rnd_dev, 3, 1));
echo mt_rand();
Score: 0

I made a PHP class for generating random 5 numbers and strings PHPRandomValue

It uses "mcrypt_create_iv(4, MCRYPT_DEV_URANDOM)" to 4 generate random numbers and values. I made 3 it while working on a crypto project because 2 I needed a safe random value generator. Here's 1 an example usage

$randomValue = new RandomValue;

$randomValue->randomNumber(): = -3880998

$randomValue->randomNumberBetween(1,10): = 2

$randomValue->randomTextString(): = CfCkKDHRgUULdGWcSqP4

$randomValue->randomTextString(10):  = LorPIxaeEY

$randomValue->randomKey(): = C7al8tX9.gqYLf2ImVt/!$NOY79T5sNCT/6Q.$!.6Gf/Q5zpa3

$randomValue->randomKey(10):  = RDV.dc6Ai/

More Related questions