Is srand(time(NULL)) bad?
Asked Answered
B

1

18

In rand() considered harmful it is pointed out that srand(time(NULL)) is bad because srand takes an unsigned int, but for Microsoft's compiler, time_t by default is a 64-bit number, therefore a narrowing conversion happens. However, time_t is implementation-defined.

Since I see srand(time(NULL)) so prevalent (even on this site), should it be discouraged?

Banker answered 5/10, 2014 at 20:15 Comment(7)
There are better ways of randomizing, why not use them?Clevey
It's about the best you can do in C, or even in C++ 98/03. C++11 added a new <random> header with new random number generation capabilities improve the situation substantially.Torquay
While true, Boost has better PRNGs that work in C++98.Vu
@DavidHeffernan Name a few please.Pandora
@Pandora Start with the functionality declared in the random headerClevey
Short answer: Use it in toy programs, don't use it for anything you're going to publish or use for any important application.Kayceekaye
Not for that reason - a 32 bit integer that counts seconds will take 136 years to overflow (time_t's are signed, so it's 136/2 starting from 1970, ie 2038; ntp uses/used uint32 from 1900, so 2036).Welcome
P
12

Since I see srand(time(NULL)) so prevalent (even on this site), should it be discouraged?

It depends on how you want to use the output from from your generator (in this case, the output of rand()).

If you only need a uniform distribution for single runs of your program, then srand(time(NULL)) is fine. This would be acceptable in a simulation where you only need a uniform distribution of numbers quickly.

If you want to submit a batch job so that multiple instances of your program run at the same time (and are effectively started at the same time), then srand(time(NULL)) will probably result in one or more instances producing the same random stream.

If you need a secure output, then you should not use srand(time(NULL)) because its often a Linear Congruential Generator (LCG). Joan Boyar taught us how to break them years ago. See Inferring sequences produced by a linear congruential generator missing low-order bits.

As for the problem with time_t, just fold it to fit the argument expected by srand if time_t is too large. You might even fold in the process PID so that batch simulation jobs work as intended/expected.

Pashm answered 5/10, 2014 at 20:30 Comment(1)
When /dev/urandom is not available, to make the seed harder to guess, and to avoid collisions, Perl mixes the process ID, a stack pointer and the time (preferably seconds + microseconds from gettimeofday). perl5.git.perl.org/perl.git/blob/v5.20.1:/util.c#l4409Kalvn

© 2022 - 2024 — McMap. All rights reserved.