random_bytes()WP 1.0

Unless open_basedir is enabled, use /dev/urandom for random numbers in accordance with best practices

Why we use /dev/urandom and not /dev/random

Хуков нет.

Возвращает

Строку.

Использование

random_bytes( $bytes );
$bytes(int) (обязательный)
-

Код random_bytes() WP 6.1.1

function random_bytes($bytes)
{
    /** @var resource $fp */
    static $fp = null;

    /**
     * This block should only be run once
     */
    if (empty($fp)) {
        /**
         * We don't want to ever read C:\dev\random, only /dev/urandom on
         * Unix-like operating systems. While we guard against this
         * condition in random.php, it doesn't hurt to be defensive in depth
         * here.
         *
         * To that end, we only try to open /dev/urandom if we're on a Unix-
         * like operating system (which means the directory separator is set
         * to "/" not "\".
         */
        if (DIRECTORY_SEPARATOR === '/') {
            if (!is_readable('/dev/urandom')) {
                throw new Exception(
                    'Environment misconfiguration: ' .
                    '/dev/urandom cannot be read.'
                );
            }
            /**
             * We use /dev/urandom if it is a char device.
             * We never fall back to /dev/random
             */
            /** @var resource|bool $fp */
            $fp = fopen('/dev/urandom', 'rb');
            if (is_resource($fp)) {
                /** @var array<string, int> $st */
                $st = fstat($fp);
                if (($st['mode'] & 0170000) !== 020000) {
                    fclose($fp);
                    $fp = false;
                }
            }
        }

        if (is_resource($fp)) {
            /**
             * stream_set_read_buffer() does not exist in HHVM
             *
             * If we don't set the stream's read buffer to 0, PHP will
             * internally buffer 8192 bytes, which can waste entropy
             *
             * stream_set_read_buffer returns 0 on success
             */
            if (is_callable('stream_set_read_buffer')) {
                stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
            }
            if (is_callable('stream_set_chunk_size')) {
                stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
            }
        }
    }

    try {
        /** @var int $bytes */
        $bytes = RandomCompat_intval($bytes);
    } catch (TypeError $ex) {
        throw new TypeError(
            'random_bytes(): $bytes must be an integer'
        );
    }

    if ($bytes < 1) {
        throw new Error(
            'Length must be greater than 0'
        );
    }

    /**
     * This if() block only runs if we managed to open a file handle
     *
     * It does not belong in an else {} block, because the above
     * if (empty($fp)) line is logic that should only be run once per
     * page load.
     */
    if (is_resource($fp)) {
        /**
         * @var int
         */
        $remaining = $bytes;

        /**
         * @var string|bool
         */
        $buf = '';

        /**
         * We use fread() in a loop to protect against partial reads
         */
        do {
            /**
             * @var string|bool
             */
            $read = fread($fp, $remaining);
            if (!is_string($read)) {
                /**
                 * We cannot safely read from the file. Exit the
                 * do-while loop and trigger the exception condition
                 *
                 * @var string|bool
                 */
                $buf = false;
                break;
            }
            /**
             * Decrease the number of bytes returned from remaining
             */
            $remaining -= RandomCompat_strlen($read);
            /**
             * @var string $buf
             */
            $buf .= $read;
        } while ($remaining > 0);

        /**
         * Is our result valid?
         * @var string|bool $buf
         */
        if (is_string($buf)) {
            if (RandomCompat_strlen($buf) === $bytes) {
                /**
                 * Return our random entropy buffer here:
                 */
                return $buf;
            }
        }
    }

    /**
     * If we reach here, PHP has failed us.
     */
    throw new Exception(
        'Error reading from source device'
    );
}