Lawrence D¹Oliveiro
2005-07-16 22:02:48 UTC
glibc seems to have 3 different lots of pseudorandom number generator
calls. Which one would people recommend to use?
There's old rand/rand_r/srand, which is probably the most popular, but
only has 31 bits of state. Then there's the rand48 calls (drand48 et
al), which have 48 bits of state--much better. Finally there's
random/srandom/initstate/setstate, which allows for up to 496 bits of
internal state! Unfortunately, these only allow specifying a 32-bit
seed, which seems dumb.
All in all, I think the rand48 calls look like the best ones to use.
There is this note near the end of the man page:
These functions are declared obsolete by SVID 3, which states that
rand(3) should be used instead.
But then, SVID 3 itself is obsolete, so I expect this can be ignored.
Here's a function I came up with initialize the rand48 seed:
bool InitRand48
(
bool TrueRandom
)
/* reads 6 bytes from /dev/random (if TrueRandom) or /dev/urandom
(if not TrueRandom) and passes these to seed48. Returns true iff
successful. errno will be set on failure. */
{
bool Success;
int RandFile;
ushort Seed[3];
RandFile = NilFileFD;
Success = false; /* to begin with */
do /*once*/
{
RandFile = open(TrueRandom ? "/dev/random" : "/dev/urandom",
O_RDONLY);
if (RandFile < 0)
break;
const ssize_t BytesRead = read(RandFile, (void *)Seed, 6);
if (BytesRead < 6)
break;
(void)seed48(Seed);
/* All done */
Success = true;
}
while (false);
CloseFileVar(&RandFile);
return
Success;
} /*InitRand48*/
calls. Which one would people recommend to use?
There's old rand/rand_r/srand, which is probably the most popular, but
only has 31 bits of state. Then there's the rand48 calls (drand48 et
al), which have 48 bits of state--much better. Finally there's
random/srandom/initstate/setstate, which allows for up to 496 bits of
internal state! Unfortunately, these only allow specifying a 32-bit
seed, which seems dumb.
All in all, I think the rand48 calls look like the best ones to use.
There is this note near the end of the man page:
These functions are declared obsolete by SVID 3, which states that
rand(3) should be used instead.
But then, SVID 3 itself is obsolete, so I expect this can be ignored.
Here's a function I came up with initialize the rand48 seed:
bool InitRand48
(
bool TrueRandom
)
/* reads 6 bytes from /dev/random (if TrueRandom) or /dev/urandom
(if not TrueRandom) and passes these to seed48. Returns true iff
successful. errno will be set on failure. */
{
bool Success;
int RandFile;
ushort Seed[3];
RandFile = NilFileFD;
Success = false; /* to begin with */
do /*once*/
{
RandFile = open(TrueRandom ? "/dev/random" : "/dev/urandom",
O_RDONLY);
if (RandFile < 0)
break;
const ssize_t BytesRead = read(RandFile, (void *)Seed, 6);
if (BytesRead < 6)
break;
(void)seed48(Seed);
/* All done */
Success = true;
}
while (false);
CloseFileVar(&RandFile);
return
Success;
} /*InitRand48*/