我需要在php中做一些大数值的操作。我不得不在bcmathgmp之间做出选择,这似乎是这类东西的主要库。我需要逆模方法,这在bcmath库中是不可用的。所以我用的是GMP
现在我需要生成一个介于0和2^159-1之间的随机安全数。但是:
gmp_random_bits仅在php>=5.6.3中可用
gmp_random_range仅在php>=5.6.3中可用
gmp_random不允许我精确地指定位的数量(以及每个羔羊的位是多少,谁使用这种单元?)
我试着用openssl_random_pseudo_bytes生成这个数字。我只能用字节数,但我试过了。唯一问题:
openssl_random_pseudo_bytes(20)返回字符串
bindec(openssl_random_pseudo_bytes(20))返回0
hexdec(bin2hex(openssl_random_pseudo_bytes(20))返回0
gmp_import仅在php>=5.6.1中可用
所以,我放弃了,尝试将我的php升级到php5.6。基于this我做了:

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

但是如果我运行phpinfo(),显示的php版本仍然是5.9.9。
求求你,救命!我绝望了。谢谢!

最佳答案

以下应适用(在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 );

这使用bin2hex()
bindec()有点混乱,因为它只接受1和0的字符串,但不需要以bindec()开头,因为gmp_init()将直接接受十六进制参数。bindec()还将在输入超过PHP_INT_MAX时输出浮点值,如果输入到gmp_init()则会导致不希望的结果。但由于表示大量是您想要使用gmp的原因,因此首先不可能使用bindec()
不相关,根据OP的评论:
最后,在您的一个示例中,您尝试调用hexdec()bin2hex()bindec()的顺序:
hexdec(bin2hex(bindec(openssl_random_pseudo_bytes(20)))

没有意义,因为这试图先将二进制转换为十进制,然后将二进制转换为十六进制。
但是,如我上面的例子所示,仅仅使用bin2hex()就足够了,它与bindec()相反,接受原始二进制数据并且没有PHP_INT_MAX限制。
作为替代方案,您还可以使用unpack()
$g = gmp_init( '0x' . unpack( 'H*', openssl_random_pseudo_bytes( 20 ) )[ 1 ] );
echo gmp_strval( $g );

10-07 19:42