I need to do some operations with big numbers in PHP. I had to choose between bcmath and gmp which seem to be the main libraries available for this kind of stuff. I needed the inverse modulo method which is not available in the bcmath
library. So I'm using GMP
.
Now I need to generate a random secure number between 0 and 2^159-1. But :
gmp_random_bits
is only available in php >=5.6.3gmp_random_range
is only available in php >=5.6.3gmp_random
doesn't let me specify precisely the number of bit (and what is a bit per lamb and who works with this kind of unit ?)I tried to generate the number with openssl_random_pseudo_bytes
. I can only use bytes count, but I gave it a try. Only issue :
openssl_random_pseudo_bytes(20)
returns a stringbindec(openssl_random_pseudo_bytes(20))
returns 0hexdec(bin2hex(openssl_random_pseudo_bytes(20))
returns 0gmp_import
is only available in php >=5.6.1So, I gave up and tried to upgrade my php to php5.6. Based on this I did :
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install php5.6
sudo service apache2 restart
But if I run phpinfo()
, the php version displayed is still 5.9.9.
Please, help ! I'm desperate. Thanks a lot !
The following should work (tested in 5.5.9):
// gmp_init will interpret argument as hexadecimal when first two chars are 0x or 0X
$g = gmp_init( '0x' . bin2hex( openssl_random_pseudo_bytes( 20 ) ) );
echo gmp_strval( $g );
This uses bin2hex()
.
bindec()
is a bit confusing, in that it only accepts strings of 1s and 0s. But bindec()
was not needed to begin with, since gmp_init()
will directly accept a hexadecimal argument. bindec()
will also output a float if the input exceeds PHP_INT_MAX
, which leads to undesired results if input into gmp_init()
. But since representing large numbers were the reason you wanted to use GMP, utilizing bindec()
was out of the question to begin with.
Irrelevant, as per OP's comment:
Lastly, the order in which you tried to call hexdec()
, bin2hex()
, bindec()
, in one of your examples:
hexdec(bin2hex(bindec(openssl_random_pseudo_bytes(20)))
didn't make sense, as this tried to first convert binary to decimal but then binary to hexadecimal.
But, as shown in my above example, merely using bin2hex()
, which, contrary to bindec()
, does accept raw binary data and does not have the PHP_INT_MAX
limitation, should suffice.
As an alternative, you could also use unpack()
:
$g = gmp_init( '0x' . unpack( 'H*', openssl_random_pseudo_bytes( 20 ) )[ 1 ] );
echo gmp_strval( $g );
Check this article about random strings and integers: https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php
Restart apache service to be sure what php version you have
Please check your php version, 5.9 is not a valid php version,maybe you have 5.5.9 , valid releases are :https://secure.php.net/releases/ , you can use : sudo php -v
If the php version you have is not 5.6, and is not php7 and you want to use 5.6, remove completely your php and install php 5.6.
You can have php7 and 5.6 at the same time and switch:
https://askubuntu.com/questions/761713/how-can-i-downgrade-from-php-7-to-php-5-6-on-ubuntu-16-04