3v4l.org

run code in 300+ PHP versions simultaneously
<?php if (!function_exists('random_bytes')) { /** * PHP 5.2.0 - 5.6.x way to implement random_bytes() * * In order of preference: * 1. mcrypt_create_iv($bytes, MCRYPT_CREATE_IV) * 2. fread() /dev/arandom if available * 3. fread() /dev/urandom if available * 4. COM('CAPICOM.Utilities.1')->GetRandom() * 5. openssl_random_pseudo_bytes() */ if (function_exists('mcrypt_create_iv') && version_compare(PHP_VERSION, '5.3.7') >= 0) { /** * Powered by ext/mcrypt * * @param int $bytes * @return string */ function random_bytes($bytes) { if (!is_int($bytes)) { throw new Exception( 'Length must be an integer' ); } if ($bytes < 1) { throw new Exception( 'Length must be greater than 0' ); } // See PHP bug #55169 for why 5.3.7 is required $buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); if ($buf !== false) { if (RandomCompat_strlen($buf) === $bytes) { return $buf; } } /** * If we reach here, PHP has failed us. */ throw new Exception( 'PHP failed to generate random data.' ); } } elseif (!ini_get('open_basedir') && (is_readable('/dev/arandom') || is_readable('/dev/urandom'))) { /** * Use /dev/arandom or /dev/urandom for random numbers * * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers * * @param int $bytes * @return string */ function random_bytes($bytes) { static $fp = null; if ($fp === null) { if (is_readable('/dev/arandom')) { $fp = fopen('/dev/arandom', 'rb'); } else { $fp = fopen('/dev/urandom', 'rb'); } } if ($fp !== false) { $streamset = stream_set_read_buffer($fp, 0); if ($streamset === 0) { $remaining = $bytes; $buf = ''; do { $read = fread($fp, $remaining); if ($read === false) { // We cannot safely read from urandom. $buf = false; break; } // Decrease the number of bytes returned from remaining $remaining -= RandomCompat_strlen($read); $buf .= $read; } while ($remaining > 0); if ($buf !== false) { if (RandomCompat_strlen($buf) === $bytes) { /** * Return our random entropy buffer here: */ return $buf; } } } } /** * If we reach here, PHP has failed us. */ throw new Exception( 'PHP failed to generate random data.' ); } } elseif (extension_loaded('com_dotnet')) { /** * Windows with PHP < 5.3.0 will not have the function * openssl_random_pseudo_bytes() available, so let's use * CAPICOM to work around this deficiency. * * @param int $bytes * @return string */ function random_bytes($bytes) { $buf = ''; $util = new COM('CAPICOM.Utilities.1'); $execCount = 0; /** * Let's not let it loop forever. If we run N times and fail to * get N bytes of random data, then CAPICOM has failed us. */ do { $buf .= base64_decode($util->GetRandom($bytes, 0)); if (RandomCompat_strlen($buf) >= $bytes) { return RandomCompat_substr($buf, 0, $bytes); } ++$execCount; } while ($execCount < $bytes); /** * If we reach here, PHP has failed us. */ throw new Exception( 'PHP failed to generate random data.' ); } } elseif (function_exists('openssl_random_pseudo_bytes')) { /** * Since openssl_random_pseudo_bytes() uses openssl's * RAND_pseudo_bytes() API, which has been marked as deprecated by the * OpenSSL team, this is our last resort before failure. * * @ref https://www.openssl.org/docs/crypto/RAND_bytes.html * * @param int $bytes * @return string */ function random_bytes($bytes) { $secure = true; $buf = openssl_random_pseudo_bytes($bytes, $secure); if ($buf !== false && $secure) { if (RandomCompat_strlen($buf) === $bytes) { return $buf; } } /** * If we reach here, PHP has failed us. */ throw new Exception( 'PHP failed to generate random data.' ); } } else { /** * We don't have any more options, so let's throw an exception right now */ throw new Exception( 'There is no suitable CSPRNG installed on your system' ); } } if (!function_exists('RandomCompat_strlen')) { if (function_exists('mb_substr')) { /** * strlen() implementation that isn't brittle to mbstring.func_overload * * This version uses mb_strlen() in '8bit' mode to treat strings as raw * binary rather than UTF-8, ISO-8859-1, etc * * @param string $binary_string * * @return int */ function RandomCompat_strlen($binary_string) { if (!is_string($binary_string)) { throw new InvalidArgumentException( 'RandomCompat_strlen() expects a string' ); } return mb_strlen($binary_string, '8bit'); } } else { /** * strlen() implementation that isn't brittle to mbstring.func_overload * * This version just used the default strlen() * * @param string $binary_string * * @return int */ function RandomCompat_strlen($binary_string) { if (!is_string($binary_string)) { throw new InvalidArgumentException( 'RandomCompat_strlen() expects a string' ); } return strlen($binary_string); } } } if (!function_exists('RandomCompat_substr')) { if (function_exists('mb_substr')) { /** * substr() implementation that isn't brittle to mbstring.func_overload * * This version uses mb_substr() in '8bit' mode to treat strings as raw * binary rather than UTF-8, ISO-8859-1, etc * * @param string $binary_string * @param int $start * @param int $length (optional) * * @return string */ function RandomCompat_substr($binary_string, $start, $length = null) { if (!is_string($binary_string)) { throw new InvalidArgumentException( 'RandomCompat_substr(): First argument should be a string' ); } if (!is_int($start)) { throw new InvalidArgumentException( 'RandomCompat_substr(): Second argument should be an integer' ); } if ($length === null) { /** * mb_substr($str, 0, NULL, '8bit') returns an empty string on * PHP 5.3, so we have to find the length ourselves. */ $length = RandomCompat_strlen($length) - $start; } elseif (!is_int($length)) { throw new InvalidArgumentException( 'RandomCompat_substr(): Third argument should be an integer, or omitted' ); } return mb_substr($binary_string, $start, $length, '8bit'); } } else { /** * substr() implementation that isn't brittle to mbstring.func_overload * * This version just used the default substr() * * @param string $binary_string * @param int $start * @param int $length (optional) * * @return string */ function RandomCompat_substr($binary_string, $start, $length = null) { if (!is_string($binary_string)) { throw new InvalidArgumentException( 'RandomCompat_substr(): First argument should be a string' ); } if (!is_int($start)) { throw new InvalidArgumentException( 'RandomCompat_substr(): Second argument should be an integer' ); } if ($length !== null) { if (!is_int($length)) { throw new InvalidArgumentException( 'RandomCompat_substr(): Third argument should be an integer, or omitted' ); } return substr($binary_string, $start, $length); } return substr($binary_string, $start); } } } var_dump( implode('-', [ bin2hex(random_bytes(4)), bin2hex(random_bytes(2)), bin2hex(\chr((\ord(random_bytes(1)) & 0x0F) | 0x40)) . bin2hex(random_bytes(1)), bin2hex(\chr((\ord(random_bytes(1)) & 0x3F) | 0x80)) . bin2hex(random_bytes(1)), bin2hex(random_bytes(12)) ]) );

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
7.2.00.0000.01719.70
7.1.70.0040.00417.09
7.1.60.0070.00716.86
7.1.50.0100.00716.82
7.1.00.0100.06722.44
7.0.200.0090.00616.66
7.0.100.0200.03320.09
7.0.90.0030.04320.07
7.0.80.0000.08019.98
7.0.70.0130.07319.98
7.0.60.0070.04319.92
7.0.50.0100.08020.46
7.0.40.0170.07320.14
7.0.30.0200.05720.13
7.0.20.0070.07720.10
7.0.10.0030.08019.98
7.0.00.0070.04020.06
5.6.280.0100.06721.12
5.6.250.0030.07020.65
5.6.240.0000.06720.65
5.6.230.0030.05020.76
5.6.220.0030.06720.64
5.6.210.0000.07320.62
5.6.200.0030.07320.99
5.6.190.0030.05021.08
5.6.180.0030.04321.01
5.6.170.0000.05021.06
5.6.160.0170.06321.21
5.6.150.0100.05021.05
5.6.140.0130.07321.18
5.6.130.0130.05321.05
5.6.120.0100.07721.03
5.6.110.0130.07321.12
5.6.100.0070.08021.07
5.6.90.0030.05320.98
5.6.80.0030.04320.46
5.6.70.0030.03320.36
5.6.60.0070.04020.46
5.6.50.0030.03320.45
5.6.40.0070.04020.34
5.6.30.0000.04020.43
5.6.20.0070.03020.45
5.6.10.0070.03720.42
5.6.00.0000.04020.47
5.5.380.0070.07720.40
5.5.370.0000.04320.56
5.5.360.0030.07320.40
5.5.350.0030.05720.51
5.5.340.0030.04320.69
5.5.330.0030.08320.93
5.5.320.0030.08720.78
5.5.310.0200.07020.97
5.5.300.0070.04320.90
5.5.290.0130.07020.92
5.5.280.0070.07020.95
5.5.270.0100.07020.83
5.5.260.0170.07320.84
5.5.250.0130.07720.76
5.5.240.0070.03020.17
5.5.230.0030.03720.20
5.5.220.0000.03720.25
5.5.210.0100.03720.31
5.5.200.0070.03020.30
5.5.190.0030.04320.28
5.5.180.0070.03020.02
5.5.160.0030.04020.28
5.5.150.0070.03320.25
5.5.140.0030.04020.25
5.5.130.0100.02720.21
5.5.120.0030.03320.19
5.5.110.0030.04020.12
5.5.100.0070.03020.21
5.5.90.0070.04020.13
5.5.80.0030.03320.11
5.5.70.0030.04320.04
5.5.60.0030.04020.09
5.5.50.0070.03720.00
5.5.40.0030.03720.14
5.5.30.0070.03720.10
5.5.20.0100.03320.04
5.5.10.0070.03320.09
5.5.00.0030.03720.01
5.4.450.0070.06319.54
5.4.440.0070.04319.55
5.4.430.0100.03719.16
5.4.420.0030.04319.45
5.4.410.0070.03719.41
5.4.400.0100.05718.85
5.4.390.0030.04019.04
5.4.380.0030.03718.89
5.4.370.0000.04319.03
5.4.360.0070.03719.03
5.4.350.0070.03018.90
5.4.340.0070.03718.90
5.4.320.0100.05019.13
5.4.310.0030.03719.26
5.4.300.0000.03719.02
5.4.290.0100.03319.09
5.4.280.0000.03719.16
5.4.270.0000.03318.85
5.4.260.0100.03319.13
5.4.250.0000.03318.84
5.4.240.0030.04019.22
5.4.230.0030.05318.84
5.4.220.0000.04318.84
5.4.210.0000.04019.22
5.4.200.0030.04019.20
5.4.190.0100.02719.10
5.4.180.0070.03719.02
5.4.170.0070.03719.03
5.4.160.0030.03319.07
5.4.150.0100.03318.83
5.4.140.0100.02316.46
5.4.130.0030.03716.50
5.4.120.0070.03316.33
5.4.110.0030.03016.56
5.4.100.0100.06316.52
5.4.90.0070.07316.54
5.4.80.0100.04716.51
5.4.70.0070.05716.52
5.4.60.0070.06016.50
5.4.50.0030.06716.48
5.4.40.0100.04016.41
5.4.30.0030.06316.36
5.4.20.0170.02716.52
5.4.10.0100.04016.55
5.4.00.0030.06015.91

preferences:
41.15 ms | 403 KiB | 5 Q