mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 04:58:21 +00:00
Expose Bro's linear congruence PRNG as utility function.
It was previously not possible to crank the wheel on the PRNG in a deterministic way without affecting the globally unique seed. The new extra utility function bro_prng takes a state in the form of a long int and returns the new PRNG state, now allowing arbitrary code parts to use the random number functionality. This commit also fixes a problem in the H3 constructor, which requires use of multiple seeds. The single seed passed in now serves as seed to crank out as many value needed using bro_prng.
This commit is contained in:
parent
79a6a26f9f
commit
9f74064289
3 changed files with 24 additions and 13 deletions
1
src/H3.h
1
src/H3.h
|
@ -72,6 +72,7 @@ public:
|
||||||
for ( size_t bit = 0; bit < N * CHAR_BIT; bit++ )
|
for ( size_t bit = 0; bit < N * CHAR_BIT; bit++ )
|
||||||
{
|
{
|
||||||
bit_lookup[bit] = 0;
|
bit_lookup[bit] = 0;
|
||||||
|
seed = bro_prng(seed);
|
||||||
for ( size_t i = 0; i < sizeof(T)/2; i++ )
|
for ( size_t i = 0; i < sizeof(T)/2; i++ )
|
||||||
// assume random() returns at least 16 random bits
|
// assume random() returns at least 16 random bits
|
||||||
bit_lookup[bit] = (bit_lookup[bit] << 16) | (seed & 0xFFFF);
|
bit_lookup[bit] = (bit_lookup[bit] << 16) | (seed & 0xFFFF);
|
||||||
|
|
29
src/util.cc
29
src/util.cc
|
@ -829,22 +829,29 @@ bool have_random_seed()
|
||||||
return bro_rand_determistic;
|
return bro_rand_determistic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long int bro_prng(long int state)
|
||||||
|
{
|
||||||
|
// Use our own simple linear congruence PRNG to make sure we are
|
||||||
|
// predictable across platforms.
|
||||||
|
static const long int m = 2147483647;
|
||||||
|
static const long int a = 16807;
|
||||||
|
const long int q = m / a;
|
||||||
|
const long int r = m % a;
|
||||||
|
|
||||||
|
state = a * ( state % q ) - r * ( state / q );
|
||||||
|
|
||||||
|
if ( state <= 0 )
|
||||||
|
state += m;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
long int bro_random()
|
long int bro_random()
|
||||||
{
|
{
|
||||||
if ( ! bro_rand_determistic )
|
if ( ! bro_rand_determistic )
|
||||||
return random(); // Use system PRNG.
|
return random(); // Use system PRNG.
|
||||||
|
|
||||||
// Use our own simple linear congruence PRNG to make sure we are
|
bro_rand_state = bro_prng(bro_rand_state);
|
||||||
// predictable across platforms.
|
|
||||||
const long int m = 2147483647;
|
|
||||||
const long int a = 16807;
|
|
||||||
const long int q = m / a;
|
|
||||||
const long int r = m % a;
|
|
||||||
|
|
||||||
bro_rand_state = a * ( bro_rand_state % q ) - r * ( bro_rand_state / q );
|
|
||||||
|
|
||||||
if ( bro_rand_state <= 0 )
|
|
||||||
bro_rand_state += m;
|
|
||||||
|
|
||||||
return bro_rand_state;
|
return bro_rand_state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,9 +173,12 @@ unsigned int initial_seed();
|
||||||
// Returns true if the user explicitly set a seed via init_random_seed();
|
// Returns true if the user explicitly set a seed via init_random_seed();
|
||||||
extern bool have_random_seed();
|
extern bool have_random_seed();
|
||||||
|
|
||||||
|
// A simple linear congruence PRNG. It takes its state as argument and returns
|
||||||
|
// a new random value, which can serve as state for subsequent calls.
|
||||||
|
long int bro_prng(long int state);
|
||||||
|
|
||||||
// Replacement for the system random(), to which is normally falls back
|
// Replacement for the system random(), to which is normally falls back
|
||||||
// except when a seed has been given. In that case, we use our own
|
// except when a seed has been given. In that case, the function bro_prng.
|
||||||
// predictable PRNG.
|
|
||||||
long int bro_random();
|
long int bro_random();
|
||||||
|
|
||||||
// Calls the system srandom() function with the given seed if not running
|
// Calls the system srandom() function with the given seed if not running
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue