diff options
author | Jeroen van Wolffelaar <jeroen@php.net> | 2001-08-24 23:47:27 +0000 |
---|---|---|
committer | Jeroen van Wolffelaar <jeroen@php.net> | 2001-08-24 23:47:27 +0000 |
commit | e6d996d41c30a7d4c93393b61ef1221ac47385b8 (patch) | |
tree | c8ca0fbc25ef0c1e5e3d03c25d379d9ab9d5285f | |
parent | 22354791110bab54ed370abac66cf69edd961e80 (diff) | |
download | php-git-e6d996d41c30a7d4c93393b61ef1221ac47385b8.tar.gz |
Implement (not yet totally complete) INI-logic for rand.
Seed random generators on script execution start (was
already done in some configurations by crypt, removed that)
-rw-r--r-- | ext/standard/basic_functions.c | 6 | ||||
-rw-r--r-- | ext/standard/basic_functions.h | 4 | ||||
-rw-r--r-- | ext/standard/crypt.c | 13 | ||||
-rw-r--r-- | ext/standard/lcg.c | 7 | ||||
-rw-r--r-- | ext/standard/php_crypt.h | 1 | ||||
-rw-r--r-- | ext/standard/php_rand.h | 8 | ||||
-rw-r--r-- | ext/standard/php_standard.h | 1 | ||||
-rw-r--r-- | ext/standard/rand.c | 61 |
8 files changed, 81 insertions, 20 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index dd3487e567..59ef384aa2 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -25,7 +25,6 @@ #include "php_ini.h" #include "internal_functions_registry.h" #include "php_standard.h" -#include "php_math.h" #include "php_incomplete_class.h" #include "ext/standard/info.h" #include "zend_operators.h" @@ -868,10 +867,6 @@ PHP_RINIT_FUNCTION(basic) #endif BG(user_shutdown_function_names)=NULL; -#if HAVE_CRYPT - PHP_RINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU); -#endif - #ifndef ZTS PHP_RINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU); #endif @@ -879,6 +874,7 @@ PHP_RINIT_FUNCTION(basic) PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU); PHP_RINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU); PHP_RINIT(dir)(INIT_FUNC_ARGS_PASSTHRU); + PHP_RINIT(rand)(INIT_FUNC_ARGS_PASSTHRU); #ifdef TRANS_SID if (BG(use_trans_sid)) { diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index 6001628b66..38e7a10c72 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -171,6 +171,10 @@ typedef struct { struct stat lsb; /* rand.c */ + int rand_generator; /* current ini-setting */ + int rand_generator_current; /* current (by overriding by [mt_]srand) */ + + /* rand_mt.c */ php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */ php_uint32 *next; /* next random value is computed from here */ int left; /* can *next++ this many times before reloading */ diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 5489f01a75..bdd085b5d3 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -89,8 +89,6 @@ extern char *crypt(char *__key, char *__salt); #define PHP_CRYPT_RAND php_rand() -static int php_crypt_rand_seeded=0; - PHP_MINIT_FUNCTION(crypt) { REGISTER_LONG_CONSTANT("CRYPT_SALT_LENGTH", PHP_MAX_SALT_LEN, CONST_CS | CONST_PERSISTENT); @@ -103,17 +101,6 @@ PHP_MINIT_FUNCTION(crypt) } -PHP_RINIT_FUNCTION(crypt) -{ - if(!php_crypt_rand_seeded) { - /* FIXME (jeroen): temporary fix for RAND_REDESIGN */ - php_srand_sys(time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0)); - php_crypt_rand_seeded=1; - } - return SUCCESS; -} - - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static void php_to64(char *s, long v, int n) { diff --git a/ext/standard/lcg.c b/ext/standard/lcg.c index 7ae45a0ef0..f211317d73 100644 --- a/ext/standard/lcg.c +++ b/ext/standard/lcg.c @@ -42,6 +42,11 @@ static int php_lcg_initialized = 0; * The function combines two CGs with periods of * 2^31 - 85 and 2^31 - 249. The period of this function * is equal to the product of both primes. + * + * There are only about 65k distinct starting values, that's + * not much... If PHP is running as CGI, randomness is quite bad. + * If it is run as a module, it's long-livin', so no problem in that + * case. */ #define MODMULT(a, b, c, m, s) q = s/a;s=b*(s-a*q)-c*q;if(s<0)s+=m @@ -103,5 +108,5 @@ PHP_FUNCTION(lcg_value) * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 tw=78 fdm=marker - * vim<600: sw=4 ts=4 tw=78 + * vim<600: sw=8 ts=8 tw=78 */ diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h index b4b04bbd51..a977d61055 100644 --- a/ext/standard/php_crypt.h +++ b/ext/standard/php_crypt.h @@ -26,7 +26,6 @@ PHP_FUNCTION(crypt); #if HAVE_CRYPT PHP_MINIT_FUNCTION(crypt); -PHP_RINIT_FUNCTION(crypt); #endif #endif diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h index 0d20f84225..9088588f2e 100644 --- a/ext/standard/php_rand.h +++ b/ext/standard/php_rand.h @@ -115,6 +115,14 @@ void php_srand_mt(long seed TSRMLS_DC); /* Define random generator constants */ #define RAND_SYS 1 #define RAND_MT 2 +#define RAND_LCG 3 +#define RAND_SYS_STR "system" +#define RAND_MT_STR "mt" +#define RAND_LCG_STR "lcg" + +#define RAND_DEFAULT RAND_MT +#define RAND_DEFAULT_STR RAND_MT_STR + /* BC */ #define PHP_RAND_MAX php_randmax() diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h index 536c13807e..2a05b61be7 100644 --- a/ext/standard/php_standard.h +++ b/ext/standard/php_standard.h @@ -20,6 +20,7 @@ #include "basic_functions.h" #include "php_math.h" +#include "php_rand.h" #include "php_string.h" #include "base64.h" #include "php_dir.h" diff --git a/ext/standard/rand.c b/ext/standard/rand.c index 5e1c39fbdc..72736cc4b7 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -24,6 +24,7 @@ #include "php.h" #include "php_math.h" #include "php_rand.h" +#include "php_ini.h" #include "zend_execute.h" @@ -31,6 +32,66 @@ /* See php_rand.h for information about layout */ +#define SRAND_A_RANDOM_SEED (time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0)) /* something with microtime? */ + +/* TODO: check that this function is called on the start of each script + * execution: not more often, not less often. + * + * Note that system rand is inherently thread-unsafe: A different thread can + * always eat up some rand()'s, and thus nuking your expected sequence. + * Another reason to use MT... + */ +PHP_RINIT_FUNCTION(rand) +{ + /* seed all number-generators */ + /* FIXME: or seed relevant numgen on init/update ini-entry? */ + php_srand_sys(SRAND_A_RANDOM_SEED); + php_srand_mt(SRAND_A_RANDOM_SEED); +} + +/* INI */ +static int randgen_str_to_int(char *str, int strlen) +{ + /* manually check all cases, or some loop to automate this + * kind of stuff, so that a new random number generator + * can be added more easily? + * + * --jeroen + */ + if (!strcasecmp(str,RAND_SYS_STR)) { + return RAND_SYS; + } else if (!strcasecmp(str,RAND_MT_STR)) { + return RAND_MT; + } else if (!strcasecmp(str,RAND_LCG_STR)) { + return RAND_LCG; + } + return 0; /* FIXME: include that f*** .h that has FALSE */ +} + +/* FIXME: check that this is called on initial ini-parsing too */ +/* FIXME: what if no ini-entry was present? */ +static PHP_INI_MH(OnUpdateRandGen) +{ + /* Set BG(rand_generator) to the correct integer value indicating + * ini-setting */ + BG(rand_generator) = randgen_str_to_int(new_value, new_value_length); + if (!BG(rand_generator)) { + /* FIXME: is this possible? What happens if this occurs during + * ini-parsing at startup? */ + php_error(E_WARNING,"Invalid value for random_number_generator: \"%s\"", new_value); + /* Fallback: */ + BG(rand_generator) = RAND_DEFAULT; + } +#ifdef DEBUG_RAND + printf("\nRAND-INI updated: %d\n",BG(rand_generator)); +#endif + return SUCCESS; +} + +PHP_INI_BEGIN() + PHP_INI_ENTRY("random_number_generator", RAND_DEFAULT_STR, PHP_INI_ALL, OnUpdateRandGen) +PHP_INI_END() + /* srand */ /* {{{ PHPAPI void php_srand(void) */ |