summaryrefslogtreecommitdiff
path: root/ext/gmp
diff options
context:
space:
mode:
authorLeigh <leight@gmail.com>2014-09-23 22:12:23 +0100
committerLeigh <leight@gmail.com>2014-09-23 22:12:23 +0100
commit831bb9260c314290a34635d7a907673f8e9d9063 (patch)
treebd2acaeadbf72d9386656b31b80e92ccd14c8a1f /ext/gmp
parent3d6d863ccbd10d212352462b587ae1573af4f1d1 (diff)
downloadphp-git-831bb9260c314290a34635d7a907673f8e9d9063.tar.gz
Add gmp_random_bits(bits) and gmp_random_range(min, max)
Diffstat (limited to 'ext/gmp')
-rw-r--r--ext/gmp/gmp.c85
-rw-r--r--ext/gmp/php_gmp.h2
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);