Search code examples
cunixrandomseconds

C - How to ENSURE different random number generation in C when program is executed within the same second?


For an assignment, I am supposed to ensure that, even when I execute a program within the same second, I should return different numbers. However, I've read other posts and can't quite figure out how to do so specifically within the same second. If I run the code:

int main()
{    
    srand(time(NULL));

    for(count = 0; count < 10; count++)
    {
        printf("%d\n", rand()%20 + 1);
    }

    return 0;
}

I end up with the same result when executed within the same second. Does anyone know how to mix the results within the same second? I'm operating in a Unix environment if that makes a difference. Thanks.


Solution

  • To prevent 2 programs from generating the same pseudo-random numbers from rand(), they must, at a minimum effectively use different seeds for srand().

    The source for the seeds for the 2 runs of the program could be derived from either

    1) the same source - with a mechanism for unique generation.
    2) a truly random source and the chance of same seed generation tolerable low.

    1A With #1, time() is often used, but by definition, the programs start in the same second, so simplistic use of this fails.

    1B Attempting to create a file that both program access to write something like "I started with this seed - 12345, so if you generate that seed try again".

    1C Another approach is to use a finer time as hinted by (@Will) - That's better but the finer resolution may not be enough.

    2A Some platforms provide a truly random number via a system function call, but since it depends on various esoteric system events , it is slow as compared to rand(), but useful for seeding srand(). Not all systems provide this.
    [Edit] Did not see the Unix tag till later.
    /dev/random & /dev/urandom (@Dietrich Epp) provide this feature.

    2B One can use variant human reaction time like

    printf("Press enter\n");
    unsigned u = 0;
    while (!keyboard_hit()) u++;
    srand(u);
    

    Both: Combining (via exclusive-or ^) various sources like pid(), time(), reaction_time(), etc. helps. (See @nodakai)


    Even with employing various mechanism to prevent a different seeding of a random number generator, 2 different runs still could generate the same sequence: about 1 in 20^10 (10,240,000,000,000) times per OP's code. After all these are random numbers, coming up with the same sequence could happen.

    To absolutely prevent duplication, the 2 program must communicate - at least in one direction. Maybe which ever program was first to write to a common file, the sequence generated, the next could inspect and insure the sequence it makes is different.

    // pseudo code
    n = 1;
    repeat {
      srand(time()^n^pid());
      n++;
      generate_random_number_sequence();
      attempt exclusive r/w access to shared file.
      if (file opened) {
        read file;
        if (different sequence) {
          write new sequence and fclose()
          if (no I/O errors) {
            we are done - exit
          }
        }
        fclose()
      }
      maybe sleep for a fraction of a second
      maybe quit if repeated too often
    }