I used a lot of time to make it, after I failed last time, I thought there are better ways to work around. Here is how it works:
1. Subtract the minimal value from the maximal value
2. Generate the numbers for the digits by using rand()
3. Combine the digits
4. Check if it is too large or not, if is, redo 2, if not,go on.
5. Add the minimal value to the random value.
In worst case, by chance, 10 random number need to be generated before we get a good one. Numbers like 100000, 10000.
In best case, only one will be generated, numbers like 99999, 9999
In average, one out of 5 generation, because average number are 500000
function bcrand($min, $max){ bcscale(0); if(bccomp($max,$min)!=1){ return 0; } $top = bcsub($max,$min); $length = strlen($top); $rand =''; $n = 0; while(9*$n < $length){ if($length - 9*$n >= 9){ $rand .= mt_rand(0,999999999); }else{ $rand .= mt_rand(0,str_repeat('9',$length-9*$n)); } ++$n; } while(bccomp($rand,$top)==1){ $rand = substr($rand,1,$length).mt_rand(0,9); } return bcadd($rand,$min); }
I saw another function, also called bcrand(), in PHPRPC[CHINESE], a implementation of RPC in PHP, you can find it in the bcmath.php inside the file. Here is the function for the people who can not read the Chinese website.
function bcrand($n, $s) { $lowBitMasks = array(0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff); $r = $n % 16; $q = floor($n / 16); $result = '0'; $m = '1'; for ($i = 0; $i < $q; $i++) { $rand = mt_rand(0, 0xffff); if (($q - 1 == $i) and ($r == 0) and ($s == 1)) { $rand |= 0x8000; } $result = bcadd(bcmul($m, $rand), $result); $m = bcmul($m, '65536'); } if ($r != 0) { $rand = mt_rand(0, $lowBitMasks[$r]); if ($s == 1) { $rand |= 1 << ($r - 1); } $result = bcadd(bcmul($m, $rand), $result); } return $result; }
This version is different because it returns a random n-byte number, for example, bcrand(20,0) could return 634834.
I found mine is pretty fast :-)
Recent comments
11 hours 38 min ago
1 day 1 hour ago
1 day 1 hour ago
1 day 9 hours ago
1 day 15 hours ago
2 days 14 hours ago
3 days 1 hour ago
1 week 10 hours ago
1 week 4 days ago
1 week 5 days ago