diff options
author | Leigh <leight@gmail.com> | 2014-09-23 22:12:23 +0100 |
---|---|---|
committer | Leigh <leight@gmail.com> | 2014-09-23 22:12:23 +0100 |
commit | 831bb9260c314290a34635d7a907673f8e9d9063 (patch) | |
tree | bd2acaeadbf72d9386656b31b80e92ccd14c8a1f | |
parent | 3d6d863ccbd10d212352462b587ae1573af4f1d1 (diff) | |
download | php-git-831bb9260c314290a34635d7a907673f8e9d9063.tar.gz |
Add gmp_random_bits(bits) and gmp_random_range(min, max)
-rw-r--r-- | ext/gmp/gmp.c | 85 | ||||
-rw-r--r-- | ext/gmp/php_gmp.h | 2 |
2 files changed, 78 insertions, 9 deletions
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 5e0386339c..36c8260f5b 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -104,6 +104,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random, 0, 0, 0) ZEND_ARG_INFO(0, limiter) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random_bits, 0, 0, 1) + ZEND_ARG_INFO(0, bits) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random_range, 0, 0, 2) + ZEND_ARG_INFO(0, min) + ZEND_ARG_INFO(0, max) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_setbit, 0, 0, 2) ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, index) @@ -161,6 +170,8 @@ const zend_function_entry gmp_functions[] = { ZEND_FE(gmp_cmp, arginfo_gmp_binary) ZEND_FE(gmp_sign, arginfo_gmp_unary) ZEND_FE(gmp_random, arginfo_gmp_random) + ZEND_FE(gmp_random_bits, arginfo_gmp_random_bits) + ZEND_FE(gmp_random_range, arginfo_gmp_random_range) ZEND_FE(gmp_and, arginfo_gmp_binary) ZEND_FE(gmp_or, arginfo_gmp_binary) ZEND_FE(gmp_com, arginfo_gmp_unary) @@ -1784,6 +1795,19 @@ ZEND_FUNCTION(gmp_sign) } /* }}} */ +void gmp_init_random() +{ + if (!GMPG(rand_initialized)) { + /* Initialize */ + gmp_randinit_mt(GMPG(rand_state)); + + /* Seed */ + gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED()); + + GMPG(rand_initialized) = 1; + } +} + /* {{{ proto GMP gmp_random([int limiter]) Gets random number */ ZEND_FUNCTION(gmp_random) @@ -1796,16 +1820,8 @@ ZEND_FUNCTION(gmp_random) } INIT_GMP_RETVAL(gmpnum_result); + gmp_init_random(); - if (!GMPG(rand_initialized)) { - /* Initialize */ - gmp_randinit_mt(GMPG(rand_state)); - - /* Seed */ - gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED()); - - GMPG(rand_initialized) = 1; - } #ifdef GMP_LIMB_BITS mpz_urandomb(gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * GMP_LIMB_BITS); #else @@ -1814,6 +1830,57 @@ ZEND_FUNCTION(gmp_random) } /* }}} */ +/* {{{ proto GMP gmp_random_bits(int bits) + Gets a random number in the range 0 to (2 ** n) - 1 */ +ZEND_FUNCTION(gmp_random_bits) +{ + long bits; + mpz_ptr gmpnum_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bits) == FAILURE) { + return; + } + + if (bits < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The number of bits must be positive"); + RETURN_FALSE; + } + + INIT_GMP_RETVAL(gmpnum_result); + gmp_init_random(); + + mpz_urandomb(gmpnum_result, GMPG(rand_state), bits); +} +/* }}} */ + +/* {{{ proto GMP gmp_random_range(mixed min, mixed max) + Gets a random number in the range min to max */ +ZEND_FUNCTION(gmp_random_range) +{ + zval *min_arg, *max_arg; + mpz_ptr gmpnum_min, gmpnum_max, gmpnum_result; + gmp_temp_t temp_a, temp_b; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &min_arg, &max_arg) == FAILURE) { + return; + } + + FETCH_GMP_ZVAL(gmpnum_min, min_arg, temp_a); + FETCH_GMP_ZVAL(gmpnum_max, max_arg, temp_b); + + INIT_GMP_RETVAL(gmpnum_result); + gmp_init_random(); + + mpz_sub(gmpnum_max, gmpnum_max, gmpnum_min); + mpz_add_ui(gmpnum_max, gmpnum_max, 1); + mpz_urandomm(gmpnum_result, GMPG(rand_state), gmpnum_max); + mpz_add(gmpnum_result, gmpnum_result, gmpnum_min); + + FREE_GMP_TEMP(temp_a); + FREE_GMP_TEMP(temp_b); +} +/* }}} */ + /* {{{ proto GMP gmp_and(mixed a, mixed b) Calculates logical AND of a and b */ ZEND_FUNCTION(gmp_and) diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index b3706c534d..a1a1dc262f 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -66,6 +66,8 @@ ZEND_FUNCTION(gmp_or); ZEND_FUNCTION(gmp_com); ZEND_FUNCTION(gmp_xor); ZEND_FUNCTION(gmp_random); +ZEND_FUNCTION(gmp_random_bits); +ZEND_FUNCTION(gmp_random_range); ZEND_FUNCTION(gmp_setbit); ZEND_FUNCTION(gmp_clrbit); ZEND_FUNCTION(gmp_scan0); |