Convert random values from /dev/urandom

2019-05-03 18:28发布

问题:

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.

回答1:

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;
}


回答2:

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" 
?>


回答3:

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.



回答4:

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.



标签: php random