As mentioned in the comments of mt_rand()
it is weak in security and we should use /dev/urandom instead. My problem is that from urandom I get a binary string.
How do I convert this binary string to 0-9a-zA-Z?
Looks like base_convert()
does not work here.
Just for the record the full function:
function randomFromDev($len)
{
$fp = @fopen('/dev/urandom','rb');
$result = '';
if ($fp !== FALSE) {
$result .= @fread($fp, $len);
@fclose($fp);
}
else
{
trigger_error('Can not open /dev/urandom.');
}
// convert from binary to string
$result = base64_encode($result);
// remove none url chars
$result = strtr($result, '+/', '-_');
// Remove = from the end
$result = str_replace('=', ' ', $result);
return $result;
}
You can use bin2hex for the binary to string conversion.
And PHP 7 random_bytes added urandom lookup.
<?php
$bytes = random_bytes(5);
$str = bin2hex($bytes);
var_dump($str);
// string(10) "385e33f741"
?>
just use base64_encode($yourbinaryurandomstring)
with that result you can e.g. use a hash function like sha1()
or md5()
and should be fine. You don't even have do do any conversion of "="
I'm not quite sure if the hash functions can read a binary string for their own, just give it a try.
One way of using /dev/urandom
is the function uiniqid which should fit your needs.
However, if you need true random numbers you should better use /dev/random
as /dev/urandom
is still a pseudo random number generator which use /dev/random
for seed values.
Accessing the random number stream is not that hard.
<?php
$r = unpack('v*', fread(fopen('/dev/random', 'r'),16));
$uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
$r[1], $r[2], $r[3], $r[4] & 0x0fff | 0x4000,
$r[5] & 0x3fff | 0x8000, $r[6], $r[7], $r[8]);
?>
Obviously this is not production code.