'math.randomseed()' sets a somewhat random seed

When called with no arguments, 'math.randomseed' uses time and ASLR
to generate a somewhat random seed. the initial seed when Lua starts
is generated this way.
This commit is contained in:
Roberto Ierusalimschy 2019-03-13 14:47:48 -03:00
parent c5feac2b5e
commit 9eca305e75
3 changed files with 36 additions and 20 deletions

View File

@ -597,11 +597,27 @@ static void setseed (Rand64 *state, lua_Unsigned n1, lua_Unsigned n2) {
}
/*
** Set a "random" seed. To get some randomness, use the current time
** and the address of 'L' (in case the machine does address space layout
** randomization).
*/
static void randseed (lua_State *L, RanState *state) {
lua_Unsigned seed1 = (lua_Unsigned)time(NULL);
lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
setseed(state->s, seed1, seed2);
}
static int math_randomseed (lua_State *L) {
RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
if (lua_isnone(L, 1))
randseed(L, state);
else {
lua_Integer n1 = luaL_checkinteger(L, 1);
lua_Integer n2 = luaL_optinteger(L, 2, 0);
setseed(state->s, n1, n2);
}
return 0;
}
@ -615,15 +631,10 @@ static const luaL_Reg randfuncs[] = {
/*
** Register the random functions and initialize their state.
** To give some "randomness" to the initial seed, use the current time
** and the address of 'L' (in case the machine does address space layout
** randomization).
*/
static void setrandfunc (lua_State *L) {
RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0);
lua_Unsigned seed1 = (lua_Unsigned)time(NULL);
lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
setseed(state->s, seed1, seed2);
randseed(L, state); /* initialize with a "random" seed */
luaL_setfuncs(L, randfuncs, 1);
}

View File

@ -7643,14 +7643,10 @@ is equivalent to @T{math.random(1,n)}.
The call @T{math.random(0)} produces an integer with
all bits (pseudo)random.
Lua initializes its pseudo-random generator with
a weak attempt for ``randomness'',
Lua initializes its pseudo-random generator with the equivalent of
a call to @Lid{math.randomseed} with no arguments,
so that @id{math.random} should generate
different sequences of results each time the program runs.
To ensure a required level of randomness to the initial state
(or contrarily, to have a deterministic sequence,
for instance when debugging a program),
you should call @Lid{math.randomseed} explicitly.
The results from this function have good statistical qualities,
but they are not cryptographically secure.
@ -7660,14 +7656,23 @@ some number of previous results.)
}
@LibEntry{math.randomseed (x [, y])|
@LibEntry{math.randomseed ([x [, y]])|
The integer parameters @id{x} and @id{y} are
concatenated into a 128-bit @Q{seed} that
When called with at least one argument,
the integer parameters @id{x} and @id{y} are
concatenated into a 128-bit @emphx{seed} that
is used to reinitialize the pseudo-random generator;
equal seeds produce equal sequences of numbers.
The default for @id{y} is zero.
When called with no arguments,
Lua generates a seed with
a weak attempt for randomness.
To ensure a required level of randomness to the initial state
(or contrarily, to have a deterministic sequence,
for instance when debugging a program),
you should call @Lid{math.randomseed} with explicit arguments.
}
@LibEntry{math.sin (x)|

View File

@ -838,7 +838,7 @@ do
assert(rand * 2^floatbits == res)
end
math.randomseed(0, os.time())
math.randomseed()
do -- test random for floats
local randbits = math.min(floatbits, 64) -- at most 64 random bits