On Thursday April 26 2007 04:12, Tha D0od wrote: > This is really interesting. I tried out the RANDOM thing you mentioned, > and played with it a little bit. At least in my case, I got the same > first result as you after setting RANDOM to 1. Then I unset it. After > I unset it, RANDOM no longer returned random numbers. It just returned > the value I set it to. I suppose that's what the man page means when it > says it 'loses its special properties.' I'm not sure if you can get it > to generating random numbers again after you unset it, but I haven't > really did anything too involved to verify this.
In bash-3.2/variables.c we have:
static int
brand ()
{
rseed = rseed * 1103515245 + 12345;
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
}
the brand() function is used for the $RANDOM initialization. As you can see
the math is pretty simple, and it's beyond the scope of Bash to make it more
complex, and even if it were more complex it probably wouldn't help.. it
depends more on the seed itself.
Replace with this:
rseed = (unsigned int) (labs(arc4random()) & 32767);
return rseed;
and now RANDOM=1 has no effect, $RANDOM will always change because the return
value of brand() is not consistant.
I submitted a patch to bugs-bash today, which is basically:
+#if defined(HAVE_ARC4RANDOM)
+ sbrand (arc4random());
+#else
sbrand (rseed + getpid() + NOW);
+#endif
in the get_random_number() function, plus some arc4random() checks
in ./configure to keep things portable. This does not change the behavior
of 'RANDOM=1 ; echo $RANDOM', it just uses arc4random() instead of getpid(),
for the uninitialized RANDOM stirring.
If we want to completely break 'RANDOM=1 ; echo $RANDOM' then the stirring
routines can be removed all together, and $RANDOM will always be different
and there won't be any way to affect it from Bash (I think this is the best
idea).
The shell $RANDOM variable do not seem to be a Posix standard, however for
some reason (probably before /dev/urandom became popular) it is currently
accepted that users are able to seed RANDOM themselves.
I think if you want a cheaper method of making random numbers than using
arc4random(), then make your own shell-function to stir your seed. However,
breaking 'RANDOM=1 ; echo $RANDOM' probably means the patch will never be
accepted upstream.
It is also generally accepted to not use $RANDOM from the shell for anything
important, and this environment variable has very little use in modern
systems. Use /dev/{e,u}random instead. Despite this, using arc4random() for
uninitialized $RANDOM is still valid.
This comes down to how much we're willing to trust $RANDOM, and why. We can
not count on it being random on unpatched systems, and this would make
scripts which depend on real random $RANDOM dangerous on non-patched systems.
It is not difficult to use /dev/?random instead, in a shell script.
robert
pgp0uJnkZtjck.pgp
Description: PGP signature
-- http://linuxfromscratch.org/mailman/listinfo/hlfs-dev FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
