On Sat, Feb 01, 2003 at 23:06:50 -0800, Kris Kennaway wrote:
> FreeBSD's rand() implementation has been broken for the past 23
> months, since the following commit:

> i.e. the first value returned from rand() is correlated with the seed
> given to srand().  This is a big problem unless your seed is randomly
> chosen over its entire integer range.  I noticed this because awk
> exhibits the same problem, and the script seeds the generator with a
> PID.  The script works fine under 4.x since the rand() implementation
> does not have this "feature".

Yes, first value correlation is there, but old formulae have even worse
effect "The random sequences do not vary much with the seed", as source
file comments and whole discussion about old RNG bad effects shown. I.e.  
for different time+PID sequence, especially increased monotonically, like
in common practice, you'l got the same random sequence with old formulae
(which can't be called "works fine" because this fine work was the main
reason for change). So, returning to old formulae is not an option.

The real problem is not in formulae, but in srand() funclion. This simple
patch can fix first value correlation, and I plan to commit it, if we all
agree. I not find better value for NSHUFF right now, but think
that something like 10 will be enough to fight corellation completely.
Some generating picture tests needed.

--- stdlib/rand.c.bak   Sat Jan  4 20:39:19 2003
+++ stdlib/rand.c       Sun Feb  2 11:56:01 2003
@@ -51,6 +51,8 @@
 #include <stdio.h>
 #endif /* TEST */
 
+#define NSHUFF 3
+
 static int
 do_rand(unsigned long *ctx)
 {
@@ -103,7 +105,11 @@
 srand(seed)
 u_int seed;
 {
+       int i;
+
        next = seed;
+       for (i = 0; i < NSHUFF; i++)
+               (void)do_rand(&next);
 }
 
 
@@ -117,7 +123,7 @@
 void
 sranddev()
 {
-       int fd, done;
+       int fd, done, i;
 
        done = 0;
        fd = _open("/dev/random", O_RDONLY, 0);
@@ -133,6 +139,8 @@
 
                gettimeofday(&tv, NULL);
                next = (getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk;
+               for (i = 0; i < NSHUFF; i++)
+                       (void)do_rand(&next);
        }
 }
 

-- 
Andrey A. Chernov
http://ache.pp.ru/

Attachment: msg51491/pgp00000.pgp
Description: PGP signature

Reply via email to