I'm filling an array with random numbers using $blockhash[$i] = rand().time().rand()
Then, for each random number in that array I calculate the correspondent SHA512
$SecretKey = "60674ccb549f1988439774adb82ff187e63a2dfd403a0dee852e4e4eab75a0b3";
$sha = hash_hmac('sha512', $value, $SecretKey);
Split it:
$pool = str_split($sha, 2);
Then I get the first number from the $pool array, convert hex to dec and limit it within 1 and 50:
$dec = hexdec($pool[0]) % 50 + 1;
The problem is that the numbers are not that random and I don't know why. I'm counting the frequency for each number from 1 to 50 but the numbers 1,2,3,4,5 and 6 are coming up often than the others. See graph
Why is this happening and how to fix it? Thanks!
Neither
rand()
ormt_rand()
generate truly random values.As the manual states:
See Better Random Generating PHP for an StackOverflow question that points the same issue and has some good answers.
the 2 hex characters you are converting to decimal will be in the range of 0-255. you mod that by 50 and add 1 making 1-6 (range(0-5)+1) occur 6 times over 1-256 while every other number occurs only 5 times. This would account for a ~20% increase in those numbers coming up.
You get 1-6 more often because you fetch two hexadecimal digits from the hash. That's one byte, so it can store values from
0
to255
. Then you use modulo50
. In result you get ranges0-49
,50-99
,100-149
,150-199
,200-249
and...250-255
. This last one is responsible for extra prevalence of 1-6 in your results.Solution: just use
mt_rand(1,50);
[edit]
If you really need to convert a number from 0-255 range to 1-50 range, the solution would be scaling and rounding.