Using php7, I'd like to generate a random variable length unsigned bigint(8) number - between 1 and 18446744073709551615 I found https://stackoverflow.com/a/28071695/836888 but mcrypt_create_iv has been deprecated in php 7.
Thanks
Using php7, I'd like to generate a random variable length unsigned bigint(8) number - between 1 and 18446744073709551615 I found https://stackoverflow.com/a/28071695/836888 but mcrypt_create_iv has been deprecated in php 7.
Thanks
Short answer, gmp_random_range():
$from = 0;
$to = '18446744073709551615';
$random = gmp_random_range($from, $to);
var_dump($random, (string)$random);
E.g.:
object(GMP)#1 (1) {
["num"]=>
string(20) "10366718409313808674"
}
string(20) "10366718409313808674"
Additional digressions:
MySQL's BIGINT is an 8-byte integer, what means -263 to 263-1 if signed and 0 to 264-1 if unsigned.
PHP_INT_MAX is a 4-byte value in 32-bit builds but an 8-byte value in 64-bit builds. It's signed in either case.
So if you could safely assume 64-bit PHP and you wanted signed numbers then you'd be basically done with any random generation function. You could use random_int() if you're after cryptographically secure numbers or mt_rand() otherwise:
var_dump(random_int(0, PHP_INT_MAX));
var_dump(mt_rand(0, PHP_INT_MAX));
But you want unsigned values, thus you must switch to strings. Once there, an obvious approach is to generate two integers and concatenate them as strings—the tricky part is ensuring you don't overflow your range. As alternative, you can use the GMP arbitrary precision extension, which happily has a dedicated function.
P.S. You actually mention BIGINT(8)
. That 8 is nothing but the display size when printing from compliant clients, it doesn't represent the storage range and it isn't enforced by any mean. And since you clearly state you expect up to 20 digits, it's just misleading.
This is a function you can use to generate number strings from 1
to any maximum value exceeding PHP_INT_MAX
(both maximum and result will have to be strings)
IMPORTANT: Do not use this for cryptography, as not all numbers don't have equal chances to be picked:
<?php
function notCryptoRandomDecimalString($maxStrValue){
$result = '';
$maxBegin = '';
for($i = 0; $i < strlen($maxStrValue); $i++){
$maxDigit = $maxStrValue[$i];
//if beginning of the result is same than beginning of the max,
//we limit random to current char from maximum, or else it can be from 0 to 9
if($result === $maxBegin){
$result .= random_int(0, $maxDigit);
}else{
$result .= random_int(0, 9);
}
$maxBegin .= $maxDigit;
}
//remove leading zeroes
$result = ltrim($result, '0');
//if zero was picked, default to 1
if($result === ''){
$result = '1';
}
return $result;
}
echo(notCryptoRandomDecimalString('18446744073709551615'));