Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C random() & setstate function not behaving as expected

Tags:

c

random

bsd

I am unsure why these two blocks of code give different outputs:

unsigned int seed1 = 0;
char state1[256];
initstate(seed1, state1, 256);
printf("%10ld\n", random());
printf("%10ld\n", random());
// Gives:
// 1216130483
// 1950449197

vs.

unsigned int seed1 = 0;
char state1[256];
initstate(seed1, state1, 256);
printf("%10ld\n", random());
setstate(state1);
printf("%10ld\n", random());
// Gives:
// 1216130483
// 625602885

Am I misunderstanding what setstate() does?

EDIT: Interestingly enough, look at what this gives:

unsigned int seed1 = 0;
char state1[256];
initstate(seed1, state1, 256);
printf("%10ld\n", random());
setstate(state1);
setstate(state1);
printf("%10ld\n", random());
// Gives:
// 1216130483
// 1950449197
like image 788
David Lawson Avatar asked Dec 06 '12 10:12

David Lawson


1 Answers

Both implementations are correct.

Setstate just changes a static pointer in the routine to point at your buffer.

Initstate is allowed to do the same thing, but is also allowed to alter the buffer contents first. If the PRNG is something like ARC4 or Spritz, the buffer needs to be a permutation rather than just arbitrary bits. If the PRNG is a nonlinear additive feedback generator, then at least one of the low bits somewhere in the state needs to be set or it won't work right. And some libs hash the state buffer so it won't be easy to tell what kind of PRNG is in use just from the seed+output information. They aren't required to; the lib can do exactly the same thing for initstate and setstate if the generator it's using is an LFSG or something that doesn't require any particular format or have any consistency needs for the buffer. But if you don't do initstate, and your OS uses something that has such needs, your repeatable sequence may not be as unpredictable as you'd like.

like image 170
Ray Avatar answered Sep 30 '22 01:09

Ray