3v4l.org

run code in 300+ PHP versions simultaneously
<?php /** * This class helps building secure password-hashes (BCrypt) with PHP, * to store them in the database. It is provided with comments, for * educational purposes. * * @author Martin Stoeckli - www.martinstoeckli.ch/php * @copyright Martin Stoeckli 2013, this code may be freely used in every * type of project, it is provided without warranties of any kind. */ class StoPasswordHash { /** * Generates a bcrypt hash of a password, which can be stored in a database. * @param string $password Password whose hash-value we need. * @param int $cost Controls the number of iterations. Increasing the cost * by 1, doubles the needed calculation time. Must be in the range of 4-31. * @param string $serverSideKey This key acts similar to a pepper, but * can be exchanged when necessary. In certain situations, encrypting * the hash-value can protect weak passwords from a dictionary attack. * @return string Hash-value of the password. A random salt is included. * Without passing a $serverSideKey the result has a length of 60 * characters, with a $serverSideKey the length is 108 characters. */ public static function hashBcrypt($password, $cost=10, $serverSideKey='') { if (!defined('CRYPT_BLOWFISH')) throw new Exception('The CRYPT_BLOWFISH algorithm is required (PHP 5.3).'); if ($cost < 4 || $cost > 31) throw new InvalidArgumentException('The cost factor must be a number between 4 and 31'); if (version_compare(PHP_VERSION, '5.3.7') >= 0) $algorithm = '2y'; // BCrypt, with fixed unicode problem else $algorithm = '2a'; // BCrypt // BCrypt expects nearly the same alphabet as base64_encode returns, // but instead of the '+' characters it accepts '.' characters. // BCrypt alphabet: ./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz $salt = str_replace('+', '.', StoPasswordHash::generateRandomBase64String(22)); // Create crypt parameters: $algorithm$cost$salt $cryptParams = sprintf('$%s$%02d$%s', $algorithm, $cost, $salt); $hash = crypt($password, $cryptParams); // Encrypt hash with the server side key if ($serverSideKey != '') { $encryptedHash = StoPasswordHash::encryptTwofish($hash, $serverSideKey); $hash = base64_encode($encryptedHash); } return $hash; } /** * Checks, if the password matches a given hash value. This is useful when * a user enters his password for login, to check if the password corresponds * to the hash stored in the database. * @param string $password Password to check. * @param string $existingHash Stored hash-value from the database. * @param string $serverSideKey Pass the same key that was used to encrypt * $existingHash, or omit this parameter if no key was used. * @return bool Returns true, if the password matches the hash, * otherwise false. */ public static function verify($password, $existingHash, $serverSideKey='') { if (!defined('CRYPT_BLOWFISH')) throw new Exception('The CRYPT_BLOWFISH algorithm is required (PHP 5.3).'); // Decrypt hash with the server side key if ($serverSideKey != '') { $encryptedHash = base64_decode($existingHash); $existingHash = StoPasswordHash::decryptTwofish($encryptedHash, $serverSideKey); } // The parameters that where used to generate $existingHash, will be // extracted automatically from the first 29 characters of $existingHash. $newHash = crypt($password, $existingHash); return $newHash === $existingHash; } /** * Allows to change the server-side key, or to add/remove the encryption. * @param string $existingHash Encrypted or unencrypted hash-value. * @param string $oldKey Pass the key, that was used to encrypt * $existingHash, or pass '' if the hash is not yet encrypted. * @param string $newKey Pass a new key, to encrypt $existingHash, or * pass '' to remove the encryption. * @return string New encrypted/decrypted hash-value. */ public static function changeServerSideKey($existingHash, $oldKey, $newKey) { // decrypt hash-value $hash = $existingHash; if ($oldKey != '') { $encryptedHash = base64_decode($hash); $hash = StoPasswordHash::decryptTwofish($encryptedHash, $oldKey); } // encrypt hash-value if ($newKey != '') { $encryptedHash = StoPasswordHash::encryptTwofish($hash, $newKey); $hash = base64_encode($encryptedHash); } return $hash; } /** * Generates a random string of a given length, using the random source of * the operating system. The string contains only characters of this * alphabet: +/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz * @param int $length Number of characters the string should have. * @return string A random base64 encoded string. */ protected static function generateRandomBase64String($length) { if (!defined('MCRYPT_DEV_URANDOM')) throw new Exception('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).'); // Generate random bytes, using the operating system's random source. // Since PHP 5.3 this also uses the random source on a Windows server. // Unlike /dev/random, the /dev/urandom does not block the server, if // there is not enough entropy available. $binaryLength = (int)($length * 3 / 4 + 1); $randomBinaryString = mcrypt_create_iv($binaryLength, MCRYPT_DEV_URANDOM); $randomBase64String = base64_encode($randomBinaryString); return substr($randomBase64String, 0, $length); } /** * Encrypts data with the TWOFISH algorithm. The IV vector will be * included in the resulting binary string. * @param string $data Data to encrypt. Trailing \0 characters will get lost. * @param string $key This key will be used to encrypt the data. The key * will be hashed to a binary representation before it is used. * @return string Returns the encrypted data in form of a binary string. */ public static function encryptTwofish($data, $key) { if (!defined('MCRYPT_DEV_URANDOM')) throw new Exception('The MCRYPT_DEV_URANDOM source is required (PHP 5.3).'); if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).'); // The cbc mode is preferable over the ecb mode $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, ''); // Twofish accepts a key of 32 bytes. Because usually longer strings // with only readable characters are passed, we build a binary string. $binaryKey = hash('sha256', $key, true); // Create initialization vector of 16 bytes $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM); mcrypt_generic_init($td, $binaryKey, $iv); $encryptedData = mcrypt_generic($td, $data); mcrypt_generic_deinit($td); mcrypt_module_close($td); // Combine iv and encrypted text return $iv . $encryptedData; } /** * Decrypts data, formerly encrypted with @see encryptTwofish. * @param string $encryptedData Binary string with encrypted data. * @param string $key This key will be used to decrypt the data. * @return string Returns the original decrypted data. */ public static function decryptTwofish($encryptedData, $key) { if (!defined('MCRYPT_TWOFISH')) throw new Exception('The MCRYPT_TWOFISH algorithm is required (PHP 5.3).'); $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, ''); // Extract initialization vector from encrypted data $ivSize = mcrypt_enc_get_iv_size($td); $iv = substr($encryptedData, 0, $ivSize); $encryptedData = substr($encryptedData, $ivSize); $binaryKey = hash('sha256', $key, true); mcrypt_generic_init($td, $binaryKey, $iv); $decryptedData = mdecrypt_generic($td, $encryptedData); mcrypt_generic_deinit($td); mcrypt_module_close($td); // Original data was padded with 0-characters to block-size return rtrim($decryptedData, "\0"); } protected static function calculateTwofishLength($inputLength) { $td = mcrypt_module_open(MCRYPT_TWOFISH, '', MCRYPT_MODE_CBC, ''); $ivSize = mcrypt_enc_get_iv_size($td); $blockSize = mcrypt_enc_get_block_size($td); mcrypt_module_close($td); return $ivSize + ceil($inputLength / $blockSize) * $blockSize; } } ?>

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)
8.3.60.0110.00718.28
8.3.50.0150.00318.20
8.3.40.0100.00618.61
8.3.30.0110.00418.69
8.3.20.0000.00720.29
8.3.10.0080.00020.44
8.3.00.0060.00320.76
8.2.180.0130.00316.50
8.2.170.0080.00822.96
8.2.160.0100.00320.35
8.2.150.0040.00424.18
8.2.140.0050.00324.66
8.2.130.0030.00519.23
8.2.120.0040.00426.35
8.2.110.0090.00020.96
8.2.100.0040.00817.50
8.2.90.0000.00819.15
8.2.80.0120.00017.97
8.2.70.0050.00317.50
8.2.60.0050.00317.80
8.2.50.0080.00018.09
8.2.40.0040.00420.59
8.2.30.0050.00319.24
8.2.20.0040.00417.67
8.2.10.0040.00417.89
8.2.00.0040.00417.89
8.1.280.0040.01125.92
8.1.270.0000.00823.95
8.1.260.0040.00428.09
8.1.250.0050.00328.09
8.1.240.0030.00622.80
8.1.230.0000.01217.42
8.1.220.0080.00017.74
8.1.210.0040.00418.77
8.1.200.0030.00917.10
8.1.190.0000.00817.10
8.1.180.0080.00018.10
8.1.170.0030.00618.52
8.1.160.0040.00420.77
8.1.150.0000.00718.79
8.1.140.0070.00019.42
8.1.130.0000.00917.54
8.1.120.0030.00517.39
8.1.110.0000.00817.42
8.1.100.0000.00717.37
8.1.90.0040.00417.27
8.1.80.0040.00417.30
8.1.70.0050.00317.43
8.1.60.0030.00517.39
8.1.50.0040.00417.41
8.1.40.0030.00517.45
8.1.30.0030.00517.53
8.1.20.0030.00517.61
8.1.10.0000.00817.30
8.1.00.0030.00617.29
8.0.300.0020.00518.77
8.0.290.0070.00016.75
8.0.280.0030.00518.37
8.0.270.0030.00317.32
8.0.260.0030.00317.11
8.0.250.0030.00316.80
8.0.240.0050.00316.90
8.0.230.0050.00316.88
8.0.220.0000.00716.86
8.0.210.0000.00716.80
8.0.200.0040.00416.77
8.0.190.0000.00716.76
8.0.180.0000.00716.82
8.0.170.0040.00416.81
8.0.160.0040.00316.91
8.0.150.0030.00516.86
8.0.140.0040.00416.66
8.0.130.0000.00613.20
8.0.120.0050.00516.82
8.0.110.0000.00816.75
8.0.100.0050.00316.73
8.0.90.0000.00816.88
8.0.80.0140.00716.73
8.0.70.0000.00716.92
8.0.60.0040.00416.86
8.0.50.0040.00416.72
8.0.30.0140.00317.10
8.0.20.0110.00817.40
8.0.10.0000.00816.79
8.0.00.0080.01216.63
7.4.330.0040.00015.08
7.4.320.0000.00616.36
7.4.300.0030.00316.42
7.4.290.0070.00016.41
7.4.280.0040.00416.49
7.4.270.0000.00716.45
7.4.260.0070.00016.46
7.4.250.0070.00016.34
7.4.240.0070.00016.42
7.4.230.0080.00016.41
7.4.220.0100.01016.48
7.4.210.0090.00616.44
7.4.200.0000.00716.62
7.4.160.0060.01116.39
7.4.150.0030.01417.40
7.4.140.0080.00817.86
7.4.130.0080.00916.52
7.4.120.0090.00916.51
7.4.110.0070.01016.32
7.4.100.0100.01016.33
7.4.90.0150.00816.42
7.4.80.0110.00919.39
7.4.70.0060.01616.25
7.4.60.0060.01016.36
7.4.50.0060.00916.52
7.4.40.0090.00616.37
7.4.30.0130.00316.36
7.4.00.0020.01714.73
7.3.330.0020.00213.00
7.3.320.0000.00613.23
7.3.310.0030.00316.26
7.3.300.0030.00316.04
7.3.290.0070.00916.17
7.3.280.0070.00916.21
7.3.270.0140.00717.40
7.3.260.0080.00916.26
7.3.250.0140.00316.16
7.3.240.0140.00316.24
7.3.230.0090.00616.39
7.3.210.0080.00816.27
7.3.200.0110.00916.20
7.3.190.0100.01016.34
7.3.180.0170.00016.18
7.3.170.0160.00016.33
7.3.160.0110.00616.20
7.3.120.0030.01314.36
7.3.110.0150.00414.42
7.3.100.0000.01814.99
7.3.90.0030.00914.67
7.3.80.0030.01014.81
7.3.70.0060.00314.64
7.3.60.0110.00014.83
7.3.50.0040.00414.63
7.3.40.0030.00614.72
7.3.30.0040.00714.48
7.3.20.0080.00816.29
7.3.10.0040.01116.70
7.3.00.0080.00816.61
7.2.330.0100.01316.26
7.2.320.0060.01016.46
7.2.310.0090.01316.25
7.2.300.0030.01316.41
7.2.290.0090.00616.59
7.2.250.0100.01014.97
7.2.240.0090.00914.91
7.2.230.0040.01214.62
7.2.220.0140.00014.85
7.2.210.0030.01014.74
7.2.200.0060.00914.91
7.2.190.0080.00814.78
7.2.180.0040.00814.70
7.2.170.0060.00314.96
7.2.160.0070.00714.89
7.2.150.0040.01216.41
7.2.140.0060.00316.72
7.2.130.0000.01616.53
7.2.120.0100.00716.92
7.2.110.0090.00016.67
7.2.100.0040.00916.73
7.2.90.0040.01516.88
7.2.80.0030.00716.62
7.2.70.0060.00916.59
7.2.60.0040.01216.67
7.2.50.0030.00716.69
7.2.40.0000.01416.89
7.2.30.0070.00716.73
7.2.20.0040.00816.78
7.2.10.0040.01116.60
7.2.00.0070.00617.97
7.1.330.0070.01115.80
7.1.320.0100.00315.69
7.1.310.0060.00315.55
7.1.300.0030.00715.46
7.1.290.0100.00315.27
7.1.280.0060.00915.60
7.1.270.0030.00615.59
7.1.260.0030.00615.43
7.1.250.0110.00315.52
7.1.240.0030.00715.63
7.1.230.0060.00615.64
7.1.220.0000.01515.60
7.1.210.0120.00615.21
7.1.200.0100.00315.58
7.1.190.0070.00715.71
7.1.180.0050.00315.59
7.1.170.0030.01015.64
7.1.160.0090.00315.43
7.1.150.0060.00915.36
7.1.140.0080.00315.54
7.1.130.0130.00315.73
7.1.120.0000.01415.77
7.1.110.0070.00715.78
7.1.100.0070.00616.81
7.1.90.0000.01115.60
7.1.80.0140.00015.50
7.1.70.0030.00816.33
7.1.60.0080.01017.29
7.1.50.0070.00715.68
7.1.40.0070.00715.59
7.1.30.0030.00715.37
7.1.20.0000.01015.43
7.1.10.0070.00715.69
7.1.00.0050.04018.89
7.0.330.0000.01715.20
7.0.320.0080.00815.12
7.0.310.0000.00815.39
7.0.300.0000.00915.38
7.0.290.0020.00915.42
7.0.280.0030.00915.03
7.0.270.0040.00815.28
7.0.260.0040.00815.27
7.0.250.0040.01115.09
7.0.240.0040.01115.38
7.0.230.0070.00315.22
7.0.220.0040.00815.32
7.0.210.0080.00615.09
7.0.200.0030.00715.93
7.0.190.0040.00415.45
7.0.180.0000.01415.45
7.0.170.0030.00715.24
7.0.160.0000.00815.25
7.0.150.0000.01315.33
7.0.140.0000.00815.13
7.0.130.0060.00615.46
7.0.120.0040.00415.23
7.0.110.0000.00915.44
7.0.100.0070.00715.38
7.0.90.0040.00415.16
7.0.80.0030.00614.85
7.0.70.0040.01115.41
7.0.60.0180.03617.62
7.0.50.0050.04516.63
7.0.40.0130.02516.63
7.0.30.0170.02016.71
7.0.20.0130.03516.58
7.0.10.0100.02516.78
7.0.00.0050.04116.72
5.6.400.0080.00013.98
5.6.390.0120.00314.45
5.6.380.0080.00814.23
5.6.370.0060.00314.34
5.6.360.0030.01314.17
5.6.350.0070.01014.14
5.6.340.0070.00714.07
5.6.330.0110.00314.17
5.6.320.0130.00314.12
5.6.310.0030.01013.86
5.6.300.0120.00314.32
5.6.290.0030.01014.16
5.6.280.0080.03317.64
5.6.270.0030.00514.43
5.6.260.0060.00614.11
5.6.250.0100.00614.03
5.6.240.0000.00914.23
5.6.230.0100.00314.32
5.6.220.0040.01214.20
5.6.210.0130.04317.37
5.6.200.0030.04416.32
5.6.190.0030.02917.25
5.6.180.0020.04917.24
5.6.170.0170.04717.32
5.6.160.0100.03517.42
5.6.150.0010.02416.21
5.6.140.0050.02316.14
5.6.130.0020.04216.23
5.6.120.0080.04017.49
5.6.110.0080.03717.63
5.6.100.0070.02717.61
5.6.90.0050.02917.36
5.6.80.0070.03617.14
5.6.70.0030.00914.01
5.6.60.0090.00014.02
5.6.50.0080.00414.07
5.6.40.0070.00714.12
5.6.30.0030.01214.16
5.6.20.0030.00914.18
5.6.10.0030.01014.18
5.6.00.0090.00014.03
5.5.380.0080.00414.35
5.5.370.0090.00613.90
5.5.360.0000.01514.28
5.5.350.0070.03717.26
5.5.340.0120.03516.09
5.5.330.0090.03716.98
5.5.320.0160.02217.09
5.5.310.0130.02717.34
5.5.300.0090.03816.01
5.5.290.0050.03115.97
5.5.280.0020.02617.55
5.5.270.0050.04917.42
5.5.260.0050.04917.38
5.5.250.0030.04817.21
5.5.240.0120.03517.05
5.5.230.0080.00413.85
5.5.220.0000.00914.31
5.5.210.0070.00813.85
5.5.200.0030.01214.07
5.5.190.0100.00713.74
5.5.180.0070.00713.96
5.5.170.0110.00414.09
5.5.160.0030.00914.06
5.5.150.0000.01314.04
5.5.140.0090.00613.88
5.5.130.0090.00613.98
5.5.120.0080.00814.05
5.5.110.0050.00913.86
5.5.100.0100.01013.88
5.5.90.0100.01014.03
5.5.80.0030.00914.09
5.5.70.0000.01514.15
5.5.60.0040.01113.88
5.5.50.0040.01213.98
5.5.40.0030.01013.93
5.5.30.0030.00913.78
5.5.20.0030.00713.73
5.5.10.0040.00813.92
5.5.00.0000.00813.92

preferences:
35.91 ms | 401 KiB | 5 Q