Răsfoiți Sursa

'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.
Roberto Ierusalimschy 6 ani în urmă
părinte
comite
9eca305e75
3 a modificat fișierele cu 36 adăugiri și 20 ștergeri
  1. 21 10
      lmathlib.c
  2. 14 9
      manual/manual.of
  3. 1 1
      testes/math.lua

+ 21 - 10
lmathlib.c

@@ -301,7 +301,7 @@ static int math_type (lua_State *L) {
 
 
 /* rotate left 'x' by 'n' bits */
 /* rotate left 'x' by 'n' bits */
 static Rand64 rotl (Rand64 x, int n) {
 static Rand64 rotl (Rand64 x, int n) {
-  return (x << n) | (trim64(x) >> (64 - n)); 
+  return (x << n) | (trim64(x) >> (64 - n));
 }
 }
 
 
 static Rand64 nextrand (Rand64 *state) {
 static Rand64 nextrand (Rand64 *state) {
@@ -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) {
 static int math_randomseed (lua_State *L) {
   RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
   RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1));
-  lua_Integer n1 = luaL_checkinteger(L, 1);
-  lua_Integer n2 = luaL_optinteger(L, 2, 0);
-  setseed(state->s, n1, n2);
+  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;
   return 0;
 }
 }
 
 
@@ -615,15 +631,10 @@ static const luaL_Reg randfuncs[] = {
 
 
 /*
 /*
 ** Register the random functions and initialize their state.
 ** 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) {
 static void setrandfunc (lua_State *L) {
   RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0);
   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);
   luaL_setfuncs(L, randfuncs, 1);
 }
 }
 
 

+ 14 - 9
manual/manual.of

@@ -7643,14 +7643,10 @@ is equivalent to @T{math.random(1,n)}.
 The call @T{math.random(0)} produces an integer with
 The call @T{math.random(0)} produces an integer with
 all bits (pseudo)random.
 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
 so that @id{math.random} should generate
 different sequences of results each time the program runs.
 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,
 The results from this function have good statistical qualities,
 but they are not cryptographically secure.
 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;
 is used to reinitialize the pseudo-random generator;
 equal seeds produce equal sequences of numbers.
 equal seeds produce equal sequences of numbers.
 The default for @id{y} is zero.
 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)|
 @LibEntry{math.sin (x)|

+ 1 - 1
testes/math.lua

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