lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Jan 25, 2012 at 08:26:04PM -0200, Roberto Ierusalimschy wrote:
> > OK.  Cool.  This is a showstopper for the company I am working with for
> > rolling out embedded Lua with nginx.  Is there anything I can do to help?
> 
> what it is still missing now is how to create the initial per-state
> random seed. Suggestions included some address and arc4random. I am
> afraid that, for the backup ANSI implementation, we cannot do much
> better than something like this:
> 
>   seed = (unsigned int)time() + (unsigned int)L;
> 
> We can have better implementations for particular system. For instance,
> we can use arc4random if present, but how to detect it? Are there any
> other suggestions?
> 

What about a global function pointer, like:

	extern unsigned int (*lua_random)(void);

My DNS library uses a complementary, compile-time constant and some ANSI
standard macro magic to make it easy to specify which method to use. Here's
a working example, slightly modified from my original scheme. It just
requires that LUA_RANDOM be defined to one of the identifiers `time',
`arc4random', or `RAND_bytes'.

        #define PASTE(a, b) a ## b
        #define XPASTE(a, b) PASTE(a, b)

	#define LUA_PRNG_time         1
	#define LUA_PRNG_arc4random   2
	#define LUA_PRNG_RAND_bytes   3 /* OpenSSL */

	#define LUA_PRNG(which) \
		(XPASTE(LUA_PRNG_, which) == XPASTE(LUA_PRNG_, LUA_RANDOM))

	#if LUA_PRNG(time)
	#include <time.h>
	#elif LUA_PRNG(arc4random)
	#include <stdlib.h>
	#elif LUA_PRNG(RAND_bytes)
	#include <openssl/rand.h>
	#endif

	unsigned int lua_random(void) {
	#if LUA_PRNG(RAND_bytes)
	        unsigned r;

	        assert(1 == RAND_bytes((unsigned char *)&r, sizeof r));

	        return r;
	#else
	        return LUA_RANDOM();
	#endif
	} /* lua_random() */