com php-src: Fix mt_rand impl. Provide legacy impl . access.: ext/standard/basic_functions.c ext/s tandard/basic_functions.h ext/standard/mt_rand.c ex
t/standard/php_math.h ext/standard/php_mt_rand.h ext/standard/tests/math/mt_rand_value.phpt

From: Date: Tue, 05 Jul 2016 10:54:07 +0000
Subject: com php-src: Fix mt_rand impl. Provide legacy impl . access.: ext/standard/basic_functions.c ext/s tandard/basic_functions.h ext/standard/mt_rand.c ex
t/standard/php_math.h ext/standard/php_mt_rand.h ext/standard/tests/math/mt_rand_value.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-93065@lists.php.net to get a copy of this message
Commit: 7981a294bd2fb329d404001c369517e2953b92a6 Author: Leigh <leigh@php.net> Tue, 5 Jul 2016 11:54:07 +0100 Parents: eba6e7ce9ac721b072ee3afb1cae883b774f3714 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=7981a294bd2fb329d404001c369517e2953b92a6 Log: Fix mt_rand impl. Provide legacy impl. access. Changed paths: M ext/standard/basic_functions.c M ext/standard/basic_functions.h M ext/standard/mt_rand.c M ext/standard/php_math.h M ext/standard/php_mt_rand.h M ext/standard/tests/math/mt_rand_value.phpt Diff: diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 55e1f7e..e712d76 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 bef446d..c3b6ced 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 381f827..a684c5c 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 406fd49..91cd3e4 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 84ef191..9d926b5 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 772305a...c71b61e 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

« previous php.cvs (#93065) next »