aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-13 14:47:48 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-03-13 14:47:48 -0300
commit9eca305e75010e30342486a4139846faf1b3eccb (patch)
treedb2df6774e7c4eb63d2310772507c47e32223cdd
parentc5feac2b5edf86aa9bdc4b8acd5380f2fe9e197f (diff)
downloadlua-9eca305e75010e30342486a4139846faf1b3eccb.tar.gz
lua-9eca305e75010e30342486a4139846faf1b3eccb.tar.bz2
lua-9eca305e75010e30342486a4139846faf1b3eccb.zip
'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.
-rw-r--r--lmathlib.c31
-rw-r--r--manual/manual.of23
-rw-r--r--testes/math.lua2
3 files changed, 36 insertions, 20 deletions
diff --git a/lmathlib.c b/lmathlib.c
index f2bfff9b..e3ccc3ee 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -301,7 +301,7 @@ static int math_type (lua_State *L) {
301 301
302/* rotate left 'x' by 'n' bits */ 302/* rotate left 'x' by 'n' bits */
303static Rand64 rotl (Rand64 x, int n) { 303static Rand64 rotl (Rand64 x, int n) {
304 return (x << n) | (trim64(x) >> (64 - n)); 304 return (x << n) | (trim64(x) >> (64 - n));
305} 305}
306 306
307static Rand64 nextrand (Rand64 *state) { 307static Rand64 nextrand (Rand64 *state) {
@@ -597,11 +597,27 @@ static void setseed (Rand64 *state, lua_Unsigned n1, lua_Unsigned n2) {
597} 597}
598 598
599 599
600/*
601** Set a "random" seed. To get some randomness, use the current time
602** and the address of 'L' (in case the machine does address space layout
603** randomization).
604*/
605static void randseed (lua_State *L, RanState *state) {
606 lua_Unsigned seed1 = (lua_Unsigned)time(NULL);
607 lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
608 setseed(state->s, seed1, seed2);
609}
610
611
600static int math_randomseed (lua_State *L) { 612static int math_randomseed (lua_State *L) {
601 RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); 613 RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
602 lua_Integer n1 = luaL_checkinteger(L, 1); 614 if (lua_isnone(L, 1))
603 lua_Integer n2 = luaL_optinteger(L, 2, 0); 615 randseed(L, state);
604 setseed(state->s, n1, n2); 616 else {
617 lua_Integer n1 = luaL_checkinteger(L, 1);
618 lua_Integer n2 = luaL_optinteger(L, 2, 0);
619 setseed(state->s, n1, n2);
620 }
605 return 0; 621 return 0;
606} 622}
607 623
@@ -615,15 +631,10 @@ static const luaL_Reg randfuncs[] = {
615 631
616/* 632/*
617** Register the random functions and initialize their state. 633** Register the random functions and initialize their state.
618** To give some "randomness" to the initial seed, use the current time
619** and the address of 'L' (in case the machine does address space layout
620** randomization).
621*/ 634*/
622static void setrandfunc (lua_State *L) { 635static void setrandfunc (lua_State *L) {
623 RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); 636 RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0);
624 lua_Unsigned seed1 = (lua_Unsigned)time(NULL); 637 randseed(L, state); /* initialize with a "random" seed */
625 lua_Unsigned seed2 = (lua_Unsigned)(size_t)L;
626 setseed(state->s, seed1, seed2);
627 luaL_setfuncs(L, randfuncs, 1); 638 luaL_setfuncs(L, randfuncs, 1);
628} 639}
629 640
diff --git a/manual/manual.of b/manual/manual.of
index 2eb8773f..b47fd865 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -7643,14 +7643,10 @@ is equivalent to @T{math.random(1,n)}.
7643The call @T{math.random(0)} produces an integer with 7643The call @T{math.random(0)} produces an integer with
7644all bits (pseudo)random. 7644all bits (pseudo)random.
7645 7645
7646Lua initializes its pseudo-random generator with 7646Lua initializes its pseudo-random generator with the equivalent of
7647a weak attempt for ``randomness'', 7647a call to @Lid{math.randomseed} with no arguments,
7648so that @id{math.random} should generate 7648so that @id{math.random} should generate
7649different sequences of results each time the program runs. 7649different sequences of results each time the program runs.
7650To ensure a required level of randomness to the initial state
7651(or contrarily, to have a deterministic sequence,
7652for instance when debugging a program),
7653you should call @Lid{math.randomseed} explicitly.
7654 7650
7655The results from this function have good statistical qualities, 7651The results from this function have good statistical qualities,
7656but they are not cryptographically secure. 7652but they are not cryptographically secure.
@@ -7660,14 +7656,23 @@ some number of previous results.)
7660 7656
7661} 7657}
7662 7658
7663@LibEntry{math.randomseed (x [, y])| 7659@LibEntry{math.randomseed ([x [, y]])|
7664 7660
7665The integer parameters @id{x} and @id{y} are 7661When called with at least one argument,
7666concatenated into a 128-bit @Q{seed} that 7662the integer parameters @id{x} and @id{y} are
7663concatenated into a 128-bit @emphx{seed} that
7667is used to reinitialize the pseudo-random generator; 7664is used to reinitialize the pseudo-random generator;
7668equal seeds produce equal sequences of numbers. 7665equal seeds produce equal sequences of numbers.
7669The default for @id{y} is zero. 7666The default for @id{y} is zero.
7670 7667
7668When called with no arguments,
7669Lua generates a seed with
7670a weak attempt for randomness.
7671To ensure a required level of randomness to the initial state
7672(or contrarily, to have a deterministic sequence,
7673for instance when debugging a program),
7674you should call @Lid{math.randomseed} with explicit arguments.
7675
7671} 7676}
7672 7677
7673@LibEntry{math.sin (x)| 7678@LibEntry{math.sin (x)|
diff --git a/testes/math.lua b/testes/math.lua
index dc5b84f6..b010ff6c 100644
--- a/testes/math.lua
+++ b/testes/math.lua
@@ -838,7 +838,7 @@ do
838 assert(rand * 2^floatbits == res) 838 assert(rand * 2^floatbits == res)
839end 839end
840 840
841math.randomseed(0, os.time()) 841math.randomseed()
842 842
843do -- test random for floats 843do -- test random for floats
844 local randbits = math.min(floatbits, 64) -- at most 64 random bits 844 local randbits = math.min(floatbits, 64) -- at most 64 random bits