but from my code block above, 9999 is found often!
It's because theoretically the probability to roll "9999" is 1/10000 and the probability to roll "10000" is 1/20000 (and you make only 10 000 tries, which is not enough to test small probabilities like those).
Can you make 100 000 or even 1 000 000 tries? That would be interesting

I have streamlined the code to just do counts, printing 100k rolls in a browser is going to be murder on your computer, lol
and you can get the script to count to 1 million but not in a browser, the browser itself will time out
if you run it from a php console window it should count as high as you want.
10k tries:
Jackpots: 1
10000 prize: 3
0000-9885: 9891
9886-9985: 89
9986-9993: 6
9994-9997: 5
9998-9999: 6
100k times:
Jackpots: 11
10000 prize: 9
0000-9885: 98874
9886-9985: 973
9986-9993: 85
9994-9997: 36
9998-9999: 23
second run...
Jackpots: 8
10000 prize: 10
0000-9885: 98957
9886-9985: 914
9986-9993: 71
9994-9997: 35
9998-9999: 13
set_time_limit(360); // number of seconds to run script, default is 30
$_jackpot = $_10k_pz = $_prize1 = $_prize2 = $_prize3 = $_prize4 = $_prize5 = 0;
$tries = 100000; //Number of tires
$c=1;// Iteration count
do {
// nonce = $c;
// 12 char server seed string, 16 char client seed string
$nhash = hash_hmac('sha512',$c.':'.seed_string(12).':'.$c,$c.':'.seed_string(16).':'.$c,false);
$_no = ceil(hexdec(mb_substr($nhash, 0, 8 ))/429496.7295);
$_jackpot += ($_no == 8888);
$_10k_pz += ($_no == 10000);
$_prize1 += ($_no >= 0 && $_no <= 9885);
$_prize2 += ($_no >= 9886 && $_no <= 9985);
$_prize3 += ($_no >= 9986 && $_no <= 9993);
$_prize4 += ($_no >= 9994 && $_no <= 9997);
$_prize5 += ($_no >= 9998 && $_no <= 9999);
$c++;
} while ($c <= $tries);
echo '
[Counts out of ', $tries, ' tries]
Jackpots: ', $_jackpot, '
10000 prize: ', $_10k_pz, '
0000-9885: ', $_prize1, '
9886-9985: ', $_prize2, '
9986-9993: ', $_prize3, '
9994-9997: ', $_prize4, '
9998-9999: ', $_prize5, '
';
function make_rand($l,$h) {
mt_srand(make_seed());
return mt_rand($l,$h);
}
function make_seed() {
list($usec,$sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 65536);
}
function seed_string ($itr) {
$charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$ranStr = null;
for ($i = 0; $i < $itr; $i++) {
mt_srand(make_seed());
$ranStr[] = substr($charSet, mt_rand(0, strlen($charSet)), 1);
}
return implode($ranStr,'');
}
?>