"Andrey A. Chernov" <[EMAIL PROTECTED]> writes: > And the next bug is 32bit overflow there: > > tmp = *ctx * 62089911;
Ack, I thought the type promotion was automatic. Updated patch is attached. DES -- Dag-Erling Smorgrav - [EMAIL PROTECTED]
Index: lib/libc/stdlib/rand.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/rand.c,v retrieving revision 1.11 diff -u -r1.11 rand.c --- lib/libc/stdlib/rand.c 2 Feb 2003 14:27:51 -0000 1.11 +++ lib/libc/stdlib/rand.c 4 Feb 2003 13:44:52 -0000 @@ -52,7 +52,7 @@ #endif /* TEST */ static int -do_rand(unsigned long *ctx) +do_rand(uint32_t *ctx) { #ifdef USE_WEAK_SEEDING /* @@ -63,21 +63,23 @@ return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); #else /* !USE_WEAK_SEEDING */ /* - * Compute x = (7^5 * x) mod (2^31 - 1) - * wihout overflowing 31 bits: - * (2^31 - 1) = 127773 * (7^5) + 2836 - * From "Random number generators: good ones are hard to find", - * Park and Miller, Communications of the ACM, vol. 31, no. 10, - * October 1988, p. 1195. + * New algorithm derived from + * The Laws of Cryptography: Pseudo-random Number Generation + * by Neal R. Wagner + * http://www.cs.utsa.edu/~wagner/laws/rng.html + * which itself is derived from work by Donald E. Knuth. + * + * This is a linear congruence generator using the equation + * + * x(n+1) = (k * x(n) + a) mod m + * + * where m is 2^31 - 1, k is 62089911 and a is 0. */ - long hi, lo, x; + uint64_t tmp; - hi = *ctx / 127773; - lo = *ctx % 127773; - x = 16807 * lo - 2836 * hi; - if (x <= 0) - x += 0x7fffffff; - return ((*ctx = x) % ((u_long)RAND_MAX + 1)); + tmp = (uint64_t)*ctx * 62089911; + *ctx = (uint32_t)(tmp % (uint64_t)0x7fffffff + 1); + return (*ctx); #endif /* !USE_WEAK_SEEDING */ } @@ -85,7 +87,7 @@ int rand_r(unsigned int *ctx) { - u_long val = (u_long) *ctx; + uint32_t val = (uint32_t) *ctx; int r = do_rand(&val); *ctx = (unsigned int) val; @@ -93,7 +95,7 @@ } -static u_long next = 1; +static uint32_t next = 1; int rand()