@@ -104,6 +104,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random, 0, 0, 0)
104
104
ZEND_ARG_INFO (0 , limiter )
105
105
ZEND_END_ARG_INFO ()
106
106
107
+ ZEND_BEGIN_ARG_INFO_EX (arginfo_gmp_random_bits , 0 , 0 , 1 )
108
+ ZEND_ARG_INFO (0 , bits )
109
+ ZEND_END_ARG_INFO ()
110
+
111
+ ZEND_BEGIN_ARG_INFO_EX (arginfo_gmp_random_range , 0 , 0 , 2 )
112
+ ZEND_ARG_INFO (0 , min )
113
+ ZEND_ARG_INFO (0 , max )
114
+ ZEND_END_ARG_INFO ()
115
+
107
116
ZEND_BEGIN_ARG_INFO_EX (arginfo_gmp_setbit , 0 , 0 , 2 )
108
117
ZEND_ARG_INFO (0 , a )
109
118
ZEND_ARG_INFO (0 , index )
@@ -161,6 +170,8 @@ const zend_function_entry gmp_functions[] = {
161
170
ZEND_FE (gmp_cmp , arginfo_gmp_binary )
162
171
ZEND_FE (gmp_sign , arginfo_gmp_unary )
163
172
ZEND_FE (gmp_random , arginfo_gmp_random )
173
+ ZEND_FE (gmp_random_bits , arginfo_gmp_random_bits )
174
+ ZEND_FE (gmp_random_range , arginfo_gmp_random_range )
164
175
ZEND_FE (gmp_and , arginfo_gmp_binary )
165
176
ZEND_FE (gmp_or , arginfo_gmp_binary )
166
177
ZEND_FE (gmp_com , arginfo_gmp_unary )
@@ -1743,6 +1754,18 @@ ZEND_FUNCTION(gmp_sign)
1743
1754
}
1744
1755
/* }}} */
1745
1756
1757
+ static void gmp_init_random (TSRMLS_D )
1758
+ {
1759
+ if (!GMPG (rand_initialized )) {
1760
+ /* Initialize */
1761
+ gmp_randinit_mt (GMPG (rand_state ));
1762
+ /* Seed */
1763
+ gmp_randseed_ui (GMPG (rand_state ), GENERATE_SEED ());
1764
+
1765
+ GMPG (rand_initialized ) = 1 ;
1766
+ }
1767
+ }
1768
+
1746
1769
/* {{{ proto GMP gmp_random([int limiter])
1747
1770
Gets random number */
1748
1771
ZEND_FUNCTION (gmp_random )
@@ -1755,16 +1778,8 @@ ZEND_FUNCTION(gmp_random)
1755
1778
}
1756
1779
1757
1780
INIT_GMP_RETVAL (gmpnum_result );
1781
+ gmp_init_random (TSRMLS_C );
1758
1782
1759
- if (!GMPG (rand_initialized )) {
1760
- /* Initialize */
1761
- gmp_randinit_mt (GMPG (rand_state ));
1762
-
1763
- /* Seed */
1764
- gmp_randseed_ui (GMPG (rand_state ), GENERATE_SEED ());
1765
-
1766
- GMPG (rand_initialized ) = 1 ;
1767
- }
1768
1783
#ifdef GMP_LIMB_BITS
1769
1784
mpz_urandomb (gmpnum_result , GMPG (rand_state ), GMP_ABS (limiter ) * GMP_LIMB_BITS );
1770
1785
#else
@@ -1773,6 +1788,91 @@ ZEND_FUNCTION(gmp_random)
1773
1788
}
1774
1789
/* }}} */
1775
1790
1791
+ /* {{{ proto GMP gmp_random_bits(int bits)
1792
+ Gets a random number in the range 0 to (2 ** n) - 1 */
1793
+ ZEND_FUNCTION (gmp_random_bits )
1794
+ {
1795
+ long bits ;
1796
+ mpz_ptr gmpnum_result ;
1797
+
1798
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "l" , & bits ) == FAILURE ) {
1799
+ return ;
1800
+ }
1801
+
1802
+ if (bits <= 0 ) {
1803
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The number of bits must be positive" );
1804
+ RETURN_FALSE ;
1805
+ }
1806
+
1807
+ INIT_GMP_RETVAL (gmpnum_result );
1808
+ gmp_init_random (TSRMLS_C );
1809
+
1810
+ mpz_urandomb (gmpnum_result , GMPG (rand_state ), bits );
1811
+ }
1812
+ /* }}} */
1813
+
1814
+ /* {{{ proto GMP gmp_random_range(mixed min, mixed max)
1815
+ Gets a random number in the range min to max */
1816
+ ZEND_FUNCTION (gmp_random_range )
1817
+ {
1818
+ zval * min_arg , * max_arg ;
1819
+ mpz_ptr gmpnum_min , gmpnum_max , gmpnum_result ;
1820
+ gmp_temp_t temp_a , temp_b ;
1821
+
1822
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & min_arg , & max_arg ) == FAILURE ) {
1823
+ return ;
1824
+ }
1825
+
1826
+ gmp_init_random (TSRMLS_C );
1827
+
1828
+ FETCH_GMP_ZVAL (gmpnum_max , max_arg , temp_a );
1829
+
1830
+ if (Z_TYPE_P (min_arg ) == IS_LONG && Z_LVAL_P (min_arg ) >= 0 ) {
1831
+ if (mpz_cmp_ui (gmpnum_max , Z_LVAL_P (min_arg )) <= 0 ) {
1832
+ FREE_GMP_TEMP (temp_a );
1833
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The minimum value must be less than the maximum value" );
1834
+ RETURN_FALSE ;
1835
+ }
1836
+
1837
+ INIT_GMP_RETVAL (gmpnum_result );
1838
+
1839
+ if (Z_LVAL_P (min_arg )) {
1840
+ mpz_sub_ui (gmpnum_max , gmpnum_max , Z_LVAL_P (min_arg ));
1841
+ }
1842
+
1843
+ mpz_add_ui (gmpnum_max , gmpnum_max , 1 );
1844
+ mpz_urandomm (gmpnum_result , GMPG (rand_state ), gmpnum_max );
1845
+
1846
+ if (Z_LVAL_P (min_arg )) {
1847
+ mpz_add_ui (gmpnum_result , gmpnum_result , Z_LVAL_P (min_arg ));
1848
+ }
1849
+
1850
+ FREE_GMP_TEMP (temp_a );
1851
+
1852
+ }
1853
+ else {
1854
+ FETCH_GMP_ZVAL_DEP (gmpnum_min , min_arg , temp_b , temp_a );
1855
+
1856
+ if (mpz_cmp (gmpnum_max , gmpnum_min ) <= 0 ) {
1857
+ FREE_GMP_TEMP (temp_b );
1858
+ FREE_GMP_TEMP (temp_a );
1859
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The minimum value must be less than the maximum value" );
1860
+ RETURN_FALSE ;
1861
+ }
1862
+
1863
+ INIT_GMP_RETVAL (gmpnum_result );
1864
+
1865
+ mpz_sub (gmpnum_max , gmpnum_max , gmpnum_min );
1866
+ mpz_add_ui (gmpnum_max , gmpnum_max , 1 );
1867
+ mpz_urandomm (gmpnum_result , GMPG (rand_state ), gmpnum_max );
1868
+ mpz_add (gmpnum_result , gmpnum_result , gmpnum_min );
1869
+
1870
+ FREE_GMP_TEMP (temp_b );
1871
+ FREE_GMP_TEMP (temp_a );
1872
+ }
1873
+ }
1874
+ /* }}} */
1875
+
1776
1876
/* {{{ proto GMP gmp_and(mixed a, mixed b)
1777
1877
Calculates logical AND of a and b */
1778
1878
ZEND_FUNCTION (gmp_and )
0 commit comments