diff options
author | Leigh <leigh@php.net> | 2016-07-05 11:54:07 +0100 |
---|---|---|
committer | Leigh <leigh@php.net> | 2016-07-05 11:54:07 +0100 |
commit | 7981a294bd2fb329d404001c369517e2953b92a6 (patch) | |
tree | f1d47a0087e106a4bb8aadc7d6a567d9f38bef34 | |
parent | eba6e7ce9ac721b072ee3afb1cae883b774f3714 (diff) | |
download | php-git-7981a294bd2fb329d404001c369517e2953b92a6.tar.gz |
Fix mt_rand impl. Provide legacy impl. access.
-rw-r--r-- | ext/standard/basic_functions.c | 21 | ||||
-rw-r--r-- | ext/standard/basic_functions.h | 1 | ||||
-rw-r--r-- | ext/standard/mt_rand.c | 49 | ||||
-rw-r--r-- | ext/standard/php_math.h | 1 | ||||
-rw-r--r-- | ext/standard/php_mt_rand.h | 5 | ||||
-rw-r--r-- | ext/standard/tests/math/mt_rand_value.phpt | 35 |
6 files changed, 100 insertions, 12 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 55e1f7e2eb..e712d76216 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -35,6 +35,7 @@ #include "zend_operators.h" #include "ext/standard/php_dns.h" #include "ext/standard/php_uuencode.h" +#include "ext/standard/php_mt_rand.h" #ifdef PHP_WIN32 #include "win32/php_win32_globals.h" @@ -1887,24 +1888,29 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_srand, 0, 0, 0) ZEND_ARG_INFO(0, seed) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_mt_srand, 0, 0, 0) - ZEND_ARG_INFO(0, seed) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_rand, 0, 0, 0) ZEND_ARG_INFO(0, min) ZEND_ARG_INFO(0, max) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_getrandmax, 0) +ZEND_END_ARG_INFO() +/* }}} */ +/* {{{ mt_rand.c */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_mt_srand, 0, 0, 0) + ZEND_ARG_INFO(0, seed) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_mt_rand, 0, 0, 0) ZEND_ARG_INFO(0, min) ZEND_ARG_INFO(0, max) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_getrandmax, 0) +ZEND_BEGIN_ARG_INFO(arginfo_mt_getrandmax, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_mt_getrandmax, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_mt_rand_mode, 0, 0, 1) + ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO() /* }}} */ /* {{{ random.c */ @@ -2865,6 +2871,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(mt_rand, arginfo_mt_rand) PHP_FE(mt_srand, arginfo_mt_srand) PHP_FE(mt_getrandmax, arginfo_mt_getrandmax) + PHP_FE(mt_rand_mode, arginfo_mt_rand_mode) PHP_FE(random_bytes, arginfo_random_bytes) PHP_FE(random_int, arginfo_random_int) @@ -3479,6 +3486,7 @@ static void basic_globals_ctor(php_basic_globals *basic_globals_p) /* {{{ */ { BG(rand_is_seeded) = 0; BG(mt_rand_is_seeded) = 0; + BG(mt_rand_mode) = MT_RAND_MT19937; BG(umask) = -1; BG(next) = NULL; BG(left) = -1; @@ -3660,6 +3668,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ BASIC_MINIT_SUBMODULE(standard_filters) BASIC_MINIT_SUBMODULE(user_filters) BASIC_MINIT_SUBMODULE(password) + BASIC_MINIT_SUBMODULE(mt_rand) #if defined(HAVE_LOCALECONV) && defined(ZTS) BASIC_MINIT_SUBMODULE(localeconv) diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index bef446d60b..c3b6cedf6d 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -200,6 +200,7 @@ typedef struct _php_basic_globals { zend_bool rand_is_seeded; /* Whether rand() has been seeded */ zend_bool mt_rand_is_seeded; /* Whether mt_rand() has been seeded */ + zend_long mt_rand_mode; /* syslog.c */ char *syslog_device; diff --git a/ext/standard/mt_rand.c b/ext/standard/mt_rand.c index 381f827a95..a684c5cf72 100644 --- a/ext/standard/mt_rand.c +++ b/ext/standard/mt_rand.c @@ -91,7 +91,8 @@ #define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ #define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ -#define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((uint32_t)(-(int32_t)(loBit(u))) & 0x9908b0dfU)) +#define twist(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((uint32_t)(-(int32_t)(loBit(v))) & 0x9908b0dfU)) +#define twist_php(m,u,v) (m ^ (mixBits(u,v)>>1) ^ ((uint32_t)(-(int32_t)(loBit(u))) & 0x9908b0dfU)) /* {{{ php_mt_initialize */ @@ -125,11 +126,20 @@ static inline void php_mt_reload(void) register uint32_t *p = state; register int i; - for (i = N - M; i--; ++p) - *p = twist(p[M], p[0], p[1]); - for (i = M; --i; ++p) - *p = twist(p[M-N], p[0], p[1]); - *p = twist(p[M-N], p[0], state[0]); + if (BG(mt_rand_mode) == MT_RAND_MT19937) { + for (i = N - M; i--; ++p) + *p = twist(p[M], p[0], p[1]); + for (i = M; --i; ++p) + *p = twist(p[M-N], p[0], p[1]); + *p = twist(p[M-N], p[0], state[0]); + } + else { + for (i = N - M; i--; ++p) + *p = twist_php(p[M], p[0], p[1]); + for (i = M; --i; ++p) + *p = twist_php(p[M-N], p[0], p[1]); + *p = twist_php(p[M-N], p[0], state[0]); + } BG(left) = N; BG(next) = state; } @@ -267,6 +277,33 @@ PHP_FUNCTION(mt_getrandmax) } /* }}} */ +/* {{{ proto int mt_rand_mode(int) + Switch mt_rand between standard and legacy modes */ +PHP_FUNCTION(mt_rand_mode) +{ + zend_long mode; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &mode) == FAILURE) { + return; + } + + switch (mode) { + case MT_RAND_PHP: + BG(mt_rand_mode) = MT_RAND_PHP; + break; + default: + BG(mt_rand_mode) = MT_RAND_MT19937; + } +} +/* }}} */ +PHP_MINIT_FUNCTION(mt_rand) +{ + REGISTER_LONG_CONSTANT("MT_RAND_MT19937", MT_RAND_MT19937, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("MT_RAND_PHP", MT_RAND_PHP, CONST_CS | CONST_PERSISTENT); + + return SUCCESS; +} + /* * Local variables: * tab-width: 4 diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 406fd49dcd..91cd3e498e 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -51,6 +51,7 @@ PHP_FUNCTION(getrandmax); PHP_FUNCTION(mt_srand); PHP_FUNCTION(mt_rand); PHP_FUNCTION(mt_getrandmax); +PHP_FUNCTION(mt_rand_mode); PHP_FUNCTION(abs); PHP_FUNCTION(ceil); PHP_FUNCTION(floor); diff --git a/ext/standard/php_mt_rand.h b/ext/standard/php_mt_rand.h index 84ef1915c6..9d926b5538 100644 --- a/ext/standard/php_mt_rand.h +++ b/ext/standard/php_mt_rand.h @@ -27,8 +27,13 @@ #define PHP_MT_RAND_MAX ((zend_long) (0x7FFFFFFF)) /* (1<<31) - 1 */ +#define MT_RAND_MT19937 0 +#define MT_RAND_PHP 1 + PHPAPI void php_mt_srand(uint32_t seed); PHPAPI uint32_t php_mt_rand(void); +PHP_MINIT_FUNCTION(mt_rand); + #endif /* PHP_MT_RAND_H */ diff --git a/ext/standard/tests/math/mt_rand_value.phpt b/ext/standard/tests/math/mt_rand_value.phpt index 772305ad63..c71b61e9b0 100644 --- a/ext/standard/tests/math/mt_rand_value.phpt +++ b/ext/standard/tests/math/mt_rand_value.phpt @@ -3,6 +3,22 @@ Test mt_rand() output --FILE-- <?php +mt_rand_mode(MT_RAND_PHP); +mt_srand(12345678); + +for ($i=0; $i<16; $i++) { + echo mt_rand().PHP_EOL; +} +echo PHP_EOL; + +$x = 0; +for ($i=0; $i<1024; $i++) { + $x ^= mt_rand(); +} +echo $x.PHP_EOL; +echo PHP_EOL; + +mt_rand_mode(MT_RAND_MT19937); mt_srand(12345678); for ($i=0; $i<16; $i++) { @@ -42,3 +58,22 @@ echo $x.PHP_EOL; 853386222 1571178311 + +527860569 +1711027313 +1280820687 +688176834 +770499160 +412773096 +813703253 +898651287 +52508912 +757323740 +511765911 +274407457 +833082629 +1923803667 +1461450755 +1301698200 + +1612214270 |