/* rand.c - Don Yang (uguu.org) IBAA random number generator. This is preferred over ISAAC because the source code to implement it is smaller. http://burtleburtle.net/bob/rand/isaac.html 05/27/12 */ #include #include #include #include typedef unsigned int Word; typedef unsigned char Byte; /* Run one iteration of IBAA, returning random number in *result */ static void Ibaa(Word *memory, Word *accumulator, Word *index, Word *result) { Word x, y; x = memory[*index]; *accumulator = ((*accumulator) << 19) ^ ((*accumulator) >> 13); memory[*index] = y = memory[x & 0xff] + *accumulator + *result; *result = memory[(y >> 8) & 0xff] + x; *index = (*index + 1) & 0xff; } /* Append a string to memory block */ static void AddBlock(Byte *input, size_t size, Byte **output) { for(; size > 0; size--) { **output = *input; ++*output; ++input; } } /* Initialize random state for Ibaa */ static void SeedIbaa(Word *memory, Word *accumulator, Word *index, Word *result) { struct timeval timestamp; Word pid; Byte *output; int i; pid = (Word)getpid(); gettimeofday(×tamp, NULL); output = (Byte*)memory; AddBlock((Byte*)&pid, sizeof(pid), &output); AddBlock((Byte*)×tamp, sizeof(timestamp), &output); AddBlock((Byte*)__TIME__, strlen(__TIME__), &output); AddBlock((Byte*)__DATE__, strlen(__DATE__), &output); for(i = 1; output < ((Byte*)memory) + 1024; i++) *output++ = (Byte)(i & 0xff); *index = *result = 0; *accumulator = 1; for(i = 0; i < 8192; i++) Ibaa(memory, accumulator, index, result); } /* Output a few random numbers to stdout */ int main(void) { Word memory[256], accumulator, index, result; int i, j; SeedIbaa(memory, &accumulator, &index, &result); for(i = 0; i < 160; i += 8) { for(j = 0; j < 8; j++) { Ibaa(memory, &accumulator, &index, &result); printf("%08x ", result); } putchar('\n'); } return 0; }