/* 6dd.c 2000 rolf.freitag at email.de */ // An example function to convert the true random bytes from /dev/rp1m, // which are equally distributed in the range 0...255, into a number which is // equally distributed in the range 0...999999. // If a guaranteed maximum answer time is needed this funktion can be enhanced with a // timeout and an instant conversion via <4 byte random number> modulo 1000000 (which will // produce an not perfect equally distributed random number) or a pseudorandom number // generator (usually this is not needed). #include #include #include #include int main (void) { unsigned int ui1 = 0; // random variable int i2 = 0; // return value union // Union of one integer and sizeof(int) random bytes (both without sign). { unsigned int ui; unsigned char uc[sizeof (int)]; } u = { 0 }; int lc = 0; // local counter FILE *fp = NULL; // file pointer to the random device fp = fopen ("/dev/rp1m", "rb"); if (fp == NULL) { perror ("\aerror: can't open device "); exit (errno); } while (lc < 2) // produce 2 times 3 decimal digits; this loop is done 1.024 times at average { fscanf (fp, "%c", u.uc); // read a true random byte fscanf (fp, "%c", &u.uc[1]); // read a true random byte ui1 = (u.uc[1] >> 2); // store the six for u unused bits if ((u.ui &= 0x3ff) < 1000) // Is it a 3 decimal digit number? { i2 += u.ui * (lc ? 1000 : 1); // the last or the first 3 decimal digits lc++; // three decimal digits done } if (lc < 2) { fscanf (fp, "%c", u.uc); // read a true random byte fscanf (fp, "%c", &u.uc[1]); // read a true random byte ui1 |= (u.uc[1] >> 2) << 6; // store the six for u unused bits if ((u.ui &= 0x3ff) < 1000) // Is it a 3 decimal digit number? { i2 += u.ui * (lc ? 1000 : 1); // the last or the first 3 decimal digits lc++; // three decimal digits done } } if ((lc < 2) && ((ui1 &= 0x3ff) < 1000)) // use 10 of the 12 unused true random bits if { // it is a 3 decimal digit number i2 += ui1 * (lc ? 1000 : 1); // the last or the first 3 decimal digits lc++; // three decimal digits done } } fclose (fp); fprintf (stdout, "Wirklich zufaellige Zufallszahl zwischen 0 und 999999, "); fprintf (stdout, "die mit einer\nWahrscheinlichkeit "); fprintf (stdout, "von genau 1/1000000 einen der Werte 0...999999 annimmt: %u\n", i2); return (0); }