@@ -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 )
@@ -1784,6 +1795,22 @@ ZEND_FUNCTION(gmp_sign)
1784
1795
}
1785
1796
/* }}} */
1786
1797
1798
+ static void gmp_init_random (TSRMLS_D )
1799
+ {
1800
+ if (!GMPG (rand_initialized )) {
1801
+ /* Initialize */
1802
+ #if GMP_42_OR_NEWER
1803
+ gmp_randinit_mt (GMPG (rand_state ));
1804
+ #else
1805
+ gmp_randinit_lc_2exp (GMPG (rand_state ), 32L );
1806
+ #endif
1807
+ /* Seed */
1808
+ gmp_randseed_ui (GMPG (rand_state ), GENERATE_SEED ());
1809
+
1810
+ GMPG (rand_initialized ) = 1 ;
1811
+ }
1812
+ }
1813
+
1787
1814
/* {{{ proto GMP gmp_random([int limiter])
1788
1815
Gets random number */
1789
1816
ZEND_FUNCTION (gmp_random )
@@ -1796,16 +1823,8 @@ ZEND_FUNCTION(gmp_random)
1796
1823
}
1797
1824
1798
1825
INIT_GMP_RETVAL (gmpnum_result );
1826
+ gmp_init_random (TSRMLS_C );
1799
1827
1800
- if (!GMPG (rand_initialized )) {
1801
- /* Initialize */
1802
- gmp_randinit_lc_2exp_size (GMPG (rand_state ), 32L );
1803
-
1804
- /* Seed */
1805
- gmp_randseed_ui (GMPG (rand_state ), GENERATE_SEED ());
1806
-
1807
- GMPG (rand_initialized ) = 1 ;
1808
- }
1809
1828
#ifdef GMP_LIMB_BITS
1810
1829
mpz_urandomb (gmpnum_result , GMPG (rand_state ), GMP_ABS (limiter ) * GMP_LIMB_BITS );
1811
1830
#else
@@ -1814,6 +1833,91 @@ ZEND_FUNCTION(gmp_random)
1814
1833
}
1815
1834
/* }}} */
1816
1835
1836
+ /* {{{ proto GMP gmp_random_bits(int bits)
1837
+ Gets a random number in the range 0 to (2 ** n) - 1 */
1838
+ ZEND_FUNCTION (gmp_random_bits )
1839
+ {
1840
+ long bits ;
1841
+ mpz_ptr gmpnum_result ;
1842
+
1843
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "l" , & bits ) == FAILURE ) {
1844
+ return ;
1845
+ }
1846
+
1847
+ if (bits <= 0 ) {
1848
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The number of bits must be positive" );
1849
+ RETURN_FALSE ;
1850
+ }
1851
+
1852
+ INIT_GMP_RETVAL (gmpnum_result );
1853
+ gmp_init_random (TSRMLS_C );
1854
+
1855
+ mpz_urandomb (gmpnum_result , GMPG (rand_state ), bits );
1856
+ }
1857
+ /* }}} */
1858
+
1859
+ /* {{{ proto GMP gmp_random_range(mixed min, mixed max)
1860
+ Gets a random number in the range min to max */
1861
+ ZEND_FUNCTION (gmp_random_range )
1862
+ {
1863
+ zval * min_arg , * max_arg ;
1864
+ mpz_ptr gmpnum_min , gmpnum_max , gmpnum_result ;
1865
+ gmp_temp_t temp_a , temp_b ;
1866
+
1867
+ if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "zz" , & min_arg , & max_arg ) == FAILURE ) {
1868
+ return ;
1869
+ }
1870
+
1871
+ gmp_init_random (TSRMLS_C );
1872
+
1873
+ FETCH_GMP_ZVAL (gmpnum_max , max_arg , temp_a );
1874
+
1875
+ if (Z_TYPE_P (min_arg ) == IS_LONG && Z_LVAL_P (min_arg ) >= 0 ) {
1876
+ if (mpz_cmp_ui (gmpnum_max , Z_LVAL_P (min_arg )) <= 0 ) {
1877
+ FREE_GMP_TEMP (temp_a );
1878
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The minimum value must be less than the maximum value" );
1879
+ RETURN_FALSE ;
1880
+ }
1881
+
1882
+ INIT_GMP_RETVAL (gmpnum_result );
1883
+
1884
+ if (Z_LVAL_P (min_arg )) {
1885
+ mpz_sub_ui (gmpnum_max , gmpnum_max , Z_LVAL_P (min_arg ));
1886
+ }
1887
+
1888
+ mpz_add_ui (gmpnum_max , gmpnum_max , 1 );
1889
+ mpz_urandomm (gmpnum_result , GMPG (rand_state ), gmpnum_max );
1890
+
1891
+ if (Z_LVAL_P (min_arg )) {
1892
+ mpz_add_ui (gmpnum_result , gmpnum_result , Z_LVAL_P (min_arg ));
1893
+ }
1894
+
1895
+ FREE_GMP_TEMP (temp_a );
1896
+
1897
+ }
1898
+ else {
1899
+ FETCH_GMP_ZVAL_DEP (gmpnum_min , min_arg , temp_b , temp_a );
1900
+
1901
+ if (mpz_cmp (gmpnum_max , gmpnum_min ) <= 0 ) {
1902
+ FREE_GMP_TEMP (temp_b );
1903
+ FREE_GMP_TEMP (temp_a );
1904
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "The minimum value must be less than the maximum value" );
1905
+ RETURN_FALSE ;
1906
+ }
1907
+
1908
+ INIT_GMP_RETVAL (gmpnum_result );
1909
+
1910
+ mpz_sub (gmpnum_max , gmpnum_max , gmpnum_min );
1911
+ mpz_add_ui (gmpnum_max , gmpnum_max , 1 );
1912
+ mpz_urandomm (gmpnum_result , GMPG (rand_state ), gmpnum_max );
1913
+ mpz_add (gmpnum_result , gmpnum_result , gmpnum_min );
1914
+
1915
+ FREE_GMP_TEMP (temp_b );
1916
+ FREE_GMP_TEMP (temp_a );
1917
+ }
1918
+ }
1919
+ /* }}} */
1920
+
1817
1921
/* {{{ proto GMP gmp_and(mixed a, mixed b)
1818
1922
Calculates logical AND of a and b */
1819
1923
ZEND_FUNCTION (gmp_and )
0 commit comments