Better seeds than time(0)?

2019-02-09 10:33发布

I understand that time(0) is commonly using for seeding random number generators and that it only becomes a problem when the program is being run more than once per second. I'm wondering what are some better seeds to consider when generating random numbers. I read about GetTickCount, timeGetTime, and QueryPerformanceCounter on Windows. Will these suffice for almost all operations or are there even better seeding options?

Here is a quick code example using the boost library:

#include <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;

int main()
{
    mt19937 randGen(42);
    uniform_int<> range(0,100);
    variate_generator<mt19937&, uniform_int<> > GetRand(randGen, range);

    for (int i = 0; i < 30; ++i)
        cout << GetRand() << endl;
}

标签: c++ boost random
11条回答
看我几分像从前
2楼-- · 2019-02-09 11:09

Too long for a comment but interesting story about 32bit seeds in the early days of online poker

The shuffling algorithm used in the ASF software always starts with an ordered deck of cards, and then generates a sequence of random numbers used to reorder the deck. In a real deck of cards, there are 52! (~2^226) possible unique shuffles. Recall that the seed for a 32-bit random number generator must be a 32-bit number, meaning that there are just over 4 billion possible seeds. Since the deck is reinitialized and the generator reseeded before each shuffle, only 4 billion possible shuffles can result from this algorithm. 4B possible shuffles is alarmingly less than 52!.

The RST-developed tool to exploit this vulnerability requires five cards from the deck to be known. Based on the five known cards, the program searches through the few hundred thousand possible shuffles and deduces which one is a perfect match. In the case of Texas Hold 'em Poker, this means the program takes as input the two cards that the cheating player is dealt, plus the first three community cards that are dealt face up (the flop). These five cards are known after the first of four rounds of betting, and are enough to determine (in real time, during play) the exact shuffle.

http://www.ibm.com/developerworks/library/s-playing/

查看更多
疯言疯语
3楼-- · 2019-02-09 11:12

The method with random number generators is to only seed it once so your example of an online game is not a problem as, potentially, the same rng will be used for each value which would have been seeded when the program was first started (perhaps several years ago).

Similarly in your own code try to seed the rng once and then use the same instance where ever required rather than creating a new rng with a new seed all over the place.

查看更多
ら.Afraid
4楼-- · 2019-02-09 11:13

Using tickCout() or anything with a high frequency is a bad idea. This is becuase the couter cycles back to zero very quickly thus gives the posability of having the same seed.

time(NULL):   Repeats every 64 years.  
tickCouter()  Repeats every X days.

You could try and get some random value from nature.
Lightining strikes world wide in the last second (appatently that is online)? (You may need to do research to see if that is variable though).

查看更多
时光不老,我们不散
5楼-- · 2019-02-09 11:15

You will need an alternative/secondary source of entropy. Depending on how much entropy you want to use, you can calculate a hash of any of the following inputs and use it as a seed for your final generator:

  • declare an unintialized random size char array on the stack
  • allocate a random bytes of memory
  • ask the user to move the mouse
  • ask the user to put random CD in the CD drive and read random bytes at random location from the first track
  • open the user's microphone or camera, collect random number of seconds of input, calculate a hash and seed
  • Windows: use CryptGenRandom to get a buffer of cryptographically random bytes
  • Unix: as others mentioned, read from /dev/random
查看更多
虎瘦雄心在
6楼-- · 2019-02-09 11:16

On unix systems, you could take a few bytes from /dev/random as a seed for your RNG. /dev/random is supposed to be very good random, using the different entropy sources available on a PC. Of course, this is completely implementation-dependent.

One case in which this could be useful is for cryptographic applications, since time(0) is relatively easy to guess.

查看更多
登录 后发表回答