[LUGOS-PROG] Bash si sladak
Borut Mrak
b at aufbix.org
Tue Mar 19 21:39:07 CET 2002
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Tuesday 19 March 2002 20:04, you wrote:
> Tisti, ki vam random ne vraca nakljucnih stevil, poskusite se tole:
>
> for ((i=1; i<5 ; i++)); do echo $RANDOM; sleep 1; done | cat
To nekako v 99% primerov ne pride v postev, ceprav ocitno resi problem...
> Iz kode za bash je videti, kot da je seme za nakljucni generator vsakic
> znova nastavljeno tako, da je pristet se sistemski cas. Sam ne morem
> preprosto preskusiti domneve.
Hmm...jaz sem zdaj posrkal k sebi source od basha. Ze prej sem hotel omenit,
da je razlika v obnasanju kadar se zadeva pozene v subshellu. Ni torej
pomemben pipe v drug program, ta "feature" se pojavi tudi ce recimo cel
expression ovijemo v oklepaje.
V variables.c je tole:
/* The random number seed. You can change this by setting RANDOM. */
static unsigned long rseed = 1;
static int last_random_value;
int
get_random_number ()
{
int rv;
/* Reset for command and process substitution. */
if (subshell_environment)
sbrand (rseed + getpid() + NOW);
do
rv = brand ();
while (rv == last_random_value);
return rv;
}
static SHELL_VAR *
get_random (var)
SHELL_VAR *var;
{
int rv;
char *p;
rv = get_random_number ();
last_random_value = rv;
p = itos (rv);
FREE (var->value);
VSETATTR (var, att_integer);
var->value = p;
return (var);
}
/* Returns a pseudo-random number between 0 and 32767. */
static int
brand ()
{
rseed = rseed * 1103515245 + 12345;
return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */
}
/* Set the random number generator seed to SEED. */
static void
sbrand (seed)
unsigned long seed;
{
rseed = seed;
last_random_value = 0;
}
Problem je torej v tem, da imamo prehitre racunalnike. Ce se zadeva pozene v
subshellu, potem se random number generator seeda *vsakic* (predvidevam,
basha ne poznam tako intimno) z isto vrednostjo ( sbrand (rseed + getpid()
+ NOW); Tale NOW bi se moral spremijat pa je ocitno zmeraj enak ), ko hocemo
prebrat kaksno random stevilo. Ker je seveda tale "random" vsakic enak
(rv==last_random_value), se brand() pozene se enkrat, nato se spet vrne prvi,
nato se brand() spet pozene 2x...
Tole je povedal povrsen pogled...malo manj povrsen pa ni tako
preprican...cetudi se tisti sbrand() klice z vsakim klicem
get_random_number(), kadar smo v subshellu, bi se rseed moral spremenit, saj
ga nastavi na rseed+getpid()...tole presega moje znanje. Mogoce pa gre za
kaksno subtilnost s tistimi bitwise operacijami v brand().
lp,
- --
Borut, vesel da ni vsakodnevno izpostavljen C-jevskemu mucenju.
b at aufbix.org
- ------------
Sorry I'm late, I'll leave early to make up for it.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iEYEARECAAYFAjyXoesACgkQRUVvbWYRhIKs9QCgySxFzoyzHF/GekcIHtRQLie6
BL8AnRG9AUq3unXs1fDAG9ZKI96yjnve
=h7S0
-----END PGP SIGNATURE-----
More information about the lugos-prog
mailing list