6

I am asking to see if there is a way of increasing the speed the srand(time(NULL)); function "refreshes"? I understand srand() produces a new seed according to time (so once a second), but I am looking for an alternative to srand() that can refresh more often than 1 second intervals.

When I run my program it produces the result it is supposed to, but the seed stays the same for essentially a second, so if the program is run multiple times a second the result stays the same.

Sorry for such a simple question, but I couldn't find an answer specifically for C anywhere online.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 3
    Use some value derived from `gettimeofday()` instead of `time()` if you need more than second accuracy. This is completely orthogonal to `srand`. – user703016 Jun 11 '15 at 07:12
  • 2
    The appropriate choice of function will be operating system dependent – samgak Jun 11 '15 at 07:18
  • 1
    In addition: if you are worried about the quality of your random numbers, [do not use `rand`](https://www.securecoding.cert.org/confluence/display/c/MSC30-C.+Do+not+use+the+rand()+function+for+generating+pseudorandom+numbers). – Jongware Jun 13 '15 at 13:01
  • Get random data from https://random.org/ (use certificate authentication to prevent MotM attack) – M.M Jun 13 '15 at 13:23

4 Answers4

4

You could try fetching a seed value from some other source. On a unix system, for example, you could fetch a random four-byte value from /dev/random:

void randomize() {
  uint32_t seed=0;
  FILE *devrnd = fopen("/dev/random","r");
  fread(&seed, 4, 1, devrnd);
  fclose(devrnd);
  srand(seed);
}
r3mainer
  • 23,981
  • 3
  • 51
  • 88
3

srand(time(NULL)); is not a function, it is rather two functions: time() which returns the current time in seconds since the epoch; and srand() which initialises the seed of the random number generator. You are initialising the seed of the rendom number generator to the current time in seconds, which is quite a reasonable thing to do.

However you have several misconceptions, you only actually need to run srand once, or at most once every few minutes, after that rand() will continue to generate more random numbers on its own, srand() is just to set an initial seed for rand to start with.

Second, if you really do want to do this, while I don't see why you would you could use a function that returns the time to a higher precision. I would suggest gettimeofday() for this purpose.

user703016
  • 37,307
  • 8
  • 87
  • 112
Vality
  • 6,577
  • 3
  • 27
  • 48
  • 2
    `so if the program is run multiple times a second`---contradicts your second paragraph. I believe OP is not calling `srand()` multiple times in code itself, the program is being run multiple times. – Sourav Ghosh Jun 11 '15 at 07:15
  • 1
    @SouravGhosh I am saying doing that is the wrong approach, the user should be persisting the program each run for longer and just running rand() to get more random numbers. Let me make this clearer – Vality Jun 11 '15 at 07:17
  • 2
    Well, I did not say you're wrong, just saying don't propose changes like `the user should be persisting the program each run for longer`. This really depends on the nature of the program, isn't it? – Sourav Ghosh Jun 11 '15 at 07:19
  • @SouravGhosh That is true, however in truth rand() should not be used for anything except toy programs anyway. I am assuming the user is just trying to learn some basic C and is flexible on how the program works somewhat. – Vality Jun 11 '15 at 07:21
  • hmm.. I thought `rand()` is reliable when used properly. I'm interested. Can you point me towards some link where I can possibly read about the downside of using `rand()` in real programs? – Sourav Ghosh Jun 11 '15 at 07:25
  • @SouravGhosh There are a wide range of sources, but here is a fairly good video on the topic http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful In summary, it isnt crypto secure (which may be fine for you), but more importantly, it doesnt have a defined range other than guaranteeing it wont return a number greater than RAND_MAX (which is at least 32767), it doesnt make any guarantees about uniformity so an implementation can have a hugely non uniform distribution. continued --> – Vality Jun 11 '15 at 07:35
  • So in essence there are no safe usages for rand, you cannot take the number as is as there are no guarantees on what the range will be, and you cannot modulo it down to a known range as the result will be non uniform, on top of that the implementation itself may be drastically non uniform. – Vality Jun 11 '15 at 07:36
  • Thanks for the info. Very useful. However the modulo bias you mentioned can be avoided by (re)setting the RAND_MAX, isn' tit? – Sourav Ghosh Jun 11 '15 at 07:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80249/discussion-between-vality-and-sourav-ghosh). – Vality Jun 11 '15 at 07:50
3

Under Windows you can use GetTickCount() instead of time(). It changes on 50ms interval (if remember correctly).

i486
  • 6,491
  • 4
  • 24
  • 41
2

I had the same issue, I found a easy fix with a high resolution clock.

#include <chrono>
#include <random>

int main() {
    long long t1 = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::srand((unsigned int)t1);
}
Alex Li
  • 246
  • 4
  • 11