initstate()
tells random what buffer to use to store information for
the next random number. You get different answers in calls to random()
because the information in your buffer state1[256]
has changed. Look at the output of the following code:
#define LEN (32)
void print_hex( char *b)
{
int i;
for( i=0; i < LEN; i++) printf("%02x ",((unsigned char *)b)[i]);
printf("\n");
}
main()
{
char state1[256], state2[256], tmp[256];
initstate( 42, state2, LEN);
initstate( 62, state1, LEN) ;
printf("buffer before random():\n");
print_hex( state1 ) ;
printf("%10ld\n", random());
printf("buffer after random():\n");
print_hex( state1 ) ;
setstate( state2 ); // Now we are free to copy data from state1
printf("buffer after setstate():\n");
print_hex( state1 ) ;
memcpy( tmp, state1, 256);
printf("copied to tmp\n");
setstate( state1 ); // Go on with original sequence
printf("next random():\n") ;
printf("%10ld\n", random());
printf("next random():\n") ;
printf("%10ld\n", random());
setstate( state2 ) ; // Again, this allows us to play with data in state1
memcpy( state1, tmp, 256);
setstate( state1 ) ;
printf("back copy:\n");
printf("random() after copy:\n") ;
printf("%10ld\n", random());
printf("next random():\n") ;
printf("%10ld\n", random());
}
This gives the output:
buffer before random():
01 00 00 00 e7 22 1d 21 f1 62 9c 90 89 72 b5 89 35 2b 97 b5 76 8c ff a8 56 14 14 7b ba 19 d9 f7
1801070350
buffer after random():
01 00 00 00 e7 22 1d 21 f1 62 9c 90 89 72 b5 89 1c 4e b4 d6 76 8c ff a8 56 14 14 7b ba 19 d9 f7
buffer after setstate():
06 00 00 00 e7 22 1d 21 f1 62 9c 90 89 72 b5 89 1c 4e b4 d6 76 8c ff a8 56 14 14 7b ba 19 d9 f7
copied to tmp
next random():
483260339
next random():
40158063
back copy:
random() after copy:
483260339
next random():
40158063
You can see that after the first call to random()
the contents of buffer state1
changes. random()
uses that area to store its state. This state is copied to buffer tmp
. Later we copy it back to state1
, and get the same sequence of random numbers.
Note that before you copy to or from a buffer that is supposed to be used for random numbers you have to tell random()
to stop using that buffer using setstate()
or initstate()
. The reason is that when setstate()
is called, the old buffer is modified to allow it to be loaded again with setstate()
.
So to get the same answer as in the original question, you have to use:
unsigned int seed1 = 42;
char state1[256], tmp[256];
initstate(seed1, state1, 256);
printf("%10ld\n", random());
initstate( 0, tmp, 256); // <- notice this
setstate( state1 ) ;
printf("%10ld\n", random());