From owner-freebsd-current Tue Feb 4 5:47:25 2003 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AD0F937B405 for ; Tue, 4 Feb 2003 05:47:17 -0800 (PST) Received: from nagual.pp.ru (pobrecita.freebsd.ru [194.87.13.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 56C0F43F43 for ; Tue, 4 Feb 2003 05:47:16 -0800 (PST) (envelope-from ache@pobrecita.freebsd.ru) Received: from pobrecita.freebsd.ru (ache@localhost [127.0.0.1]) by nagual.pp.ru (8.12.6/8.12.6) with ESMTP id h14DlFd6092998; Tue, 4 Feb 2003 16:47:15 +0300 (MSK) (envelope-from ache@pobrecita.freebsd.ru) Received: (from ache@localhost) by pobrecita.freebsd.ru (8.12.6/8.12.6/Submit) id h14DlE7n092997; Tue, 4 Feb 2003 16:47:14 +0300 (MSK) (envelope-from ache) Date: Tue, 4 Feb 2003 16:47:14 +0300 From: "Andrey A. Chernov" To: Dag-Erling Smorgrav Cc: David Schultz , Kris Kennaway , current@FreeBSD.ORG Subject: Re: rand() is broken Message-ID: <20030204134714.GA92940@nagual.pp.ru> References: <20030202090422.GA59750@nagual.pp.ru> <20030203002639.GB44914@HAL9000.homeunix.com> <20030203100002.GA73386@nagual.pp.ru> <20030204054020.GA2447@HAL9000.homeunix.com> <20030204094659.GA87303@nagual.pp.ru> <20030204115237.GA6483@HAL9000.homeunix.com> <20030204131006.GB92301@nagual.pp.ru> <20030204131748.GA92510@nagual.pp.ru> <20030204132845.GA92674@nagual.pp.ru> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="2fHTh5uZTiUOsy+g" Content-Disposition: inline In-Reply-To: <20030204132845.GA92674@nagual.pp.ru> User-Agent: Mutt/1.5.1i Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Feb 04, 2003 at 16:28:45 +0300, Andrey A. Chernov wrote: > > I'll produce working variant based on your patch... > When all done correctly, there is repeated pattern still, so some NSHUFF drop required too: 1 7 e 4 a 0 7 d 3 a 0 6 See attached patch based on -current sources. -- Andrey A. Chernov http://ache.pp.ru/ --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="rand1.patch" --- /usr/src/lib/libc/stdlib/rand.c Tue Feb 4 14:24:08 2003 +++ ./rand.c Tue Feb 4 16:40:24 2003 @@ -51,10 +51,8 @@ #include #endif /* TEST */ -#define NSHUFF 100 /* to drop part of seed -> 1st value correlation */ - static int -do_rand(unsigned long *ctx) +do_rand(uint32_t *ctx) { #ifdef USE_WEAK_SEEDING /* @@ -65,24 +63,25 @@ 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; /* Can't be initialized with 0, so use another value. */ if (*ctx == 0) *ctx = 123459876; - 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) % 2147483647; + return ((*ctx = tmp) % ((uint32_t)RAND_MAX + 1)); #endif /* !USE_WEAK_SEEDING */ } @@ -90,7 +89,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; @@ -98,7 +97,7 @@ } -static u_long next = 1; +static uint32_t next = 1; int rand() @@ -110,11 +109,7 @@ srand(seed) u_int seed; { - int i; - next = seed; - for (i = 0; i < NSHUFF; i++) - (void)do_rand(&next); } --2fHTh5uZTiUOsy+g-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message