diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-13 14:47:48 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-13 14:47:48 -0300 |
commit | 9eca305e75010e30342486a4139846faf1b3eccb (patch) | |
tree | db2df6774e7c4eb63d2310772507c47e32223cdd | |
parent | c5feac2b5edf86aa9bdc4b8acd5380f2fe9e197f (diff) | |
download | lua-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.c | 31 | ||||
-rw-r--r-- | manual/manual.of | 23 | ||||
-rw-r--r-- | testes/math.lua | 2 |
3 files changed, 36 insertions, 20 deletions
@@ -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 */ |
303 | static Rand64 rotl (Rand64 x, int n) { | 303 | static 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 | ||
307 | static Rand64 nextrand (Rand64 *state) { | 307 | static 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 | */ | ||
605 | static 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 | |||
600 | static int math_randomseed (lua_State *L) { | 612 | static 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 | */ |
622 | static void setrandfunc (lua_State *L) { | 635 | static 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)}. | |||
7643 | The call @T{math.random(0)} produces an integer with | 7643 | The call @T{math.random(0)} produces an integer with |
7644 | all bits (pseudo)random. | 7644 | all bits (pseudo)random. |
7645 | 7645 | ||
7646 | Lua initializes its pseudo-random generator with | 7646 | Lua initializes its pseudo-random generator with the equivalent of |
7647 | a weak attempt for ``randomness'', | 7647 | a call to @Lid{math.randomseed} with no arguments, |
7648 | so that @id{math.random} should generate | 7648 | so that @id{math.random} should generate |
7649 | different sequences of results each time the program runs. | 7649 | different sequences of results each time the program runs. |
7650 | To ensure a required level of randomness to the initial state | ||
7651 | (or contrarily, to have a deterministic sequence, | ||
7652 | for instance when debugging a program), | ||
7653 | you should call @Lid{math.randomseed} explicitly. | ||
7654 | 7650 | ||
7655 | The results from this function have good statistical qualities, | 7651 | The results from this function have good statistical qualities, |
7656 | but they are not cryptographically secure. | 7652 | but 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 | ||
7665 | The integer parameters @id{x} and @id{y} are | 7661 | When called with at least one argument, |
7666 | concatenated into a 128-bit @Q{seed} that | 7662 | the integer parameters @id{x} and @id{y} are |
7663 | concatenated into a 128-bit @emphx{seed} that | ||
7667 | is used to reinitialize the pseudo-random generator; | 7664 | is used to reinitialize the pseudo-random generator; |
7668 | equal seeds produce equal sequences of numbers. | 7665 | equal seeds produce equal sequences of numbers. |
7669 | The default for @id{y} is zero. | 7666 | The default for @id{y} is zero. |
7670 | 7667 | ||
7668 | When called with no arguments, | ||
7669 | Lua generates a seed with | ||
7670 | a weak attempt for randomness. | ||
7671 | To ensure a required level of randomness to the initial state | ||
7672 | (or contrarily, to have a deterministic sequence, | ||
7673 | for instance when debugging a program), | ||
7674 | you 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) |
839 | end | 839 | end |
840 | 840 | ||
841 | math.randomseed(0, os.time()) | 841 | math.randomseed() |
842 | 842 | ||
843 | do -- test random for floats | 843 | do -- 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 |