3v4l.org

run code in 300+ PHP versions simultaneously
<?php $credential = 'my password'; function BF_crypt_with_legacy_salt($string, $salt) { // PHP <=8.1.15 compat: check for $2a$ blowfish salt with dollar if(strlen($salt) == 29 && substr($salt, 0, 4) == '$2a$' && $salt[6] == '$') { $pos = strpos($salt, '$', 7); if($pos !== false) { $pos -= 7; $itoa = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // Transform provided salt into something that matches the decoding from PHP 8.1.15 if(($pos & 0x2) == 0) { // Offsets 0 and 1: truncate down to even length before the $ $cryptsalt = substr($salt, 0, 7 + ($pos & 0x1e)); } else { // Offsets 2 and 3: truncate to two before the $, and transform the char before the $ $val = strpos($itoa, $salt[7 + ($pos - 1)]); if($val === false) { return '*0'; } $cryptsalt = substr($salt, 0, 7 + ($pos - 1)).$itoa[$val & (($pos & 0x1) == 0 ? 0x30 : 0x3c)]; } for($i = 29 - strlen($cryptsalt); $i > 0; --$i) { $cryptsalt .= '.'; } // But we'll actually need a different salt value to prepend to the output $last = strpos($itoa, $salt[28]); $textsalt = substr($salt, 0, 28).$itoa[$last === false ? 0 : ($last & 0x30)]; $crypt = crypt($string, $cryptsalt); // Restore original salt in output if(substr($crypt, 0, 29) == $cryptsalt) { $crypt = $textsalt.substr($crypt, 29); } return $crypt; } } // Otherwise just pass through unchanged return crypt($string, $salt); } echo crypt($credential, '$2a$05$SomeDollarSalt9999999$')."\n"; echo BF_crypt_with_legacy_salt($credential, '$2a$05$SomeDollarSalt9999999$')."\n\n"; echo crypt($credential, '$2a$05$SomeDollarSalt999999$9')."\n"; echo BF_crypt_with_legacy_salt($credential, '$2a$05$SomeDollarSalt999999$9')."\n\n"; echo crypt($credential, '$2a$05$SomeDollarSalt99999$99')."\n"; echo BF_crypt_with_legacy_salt($credential, '$2a$05$SomeDollarSalt99999$99')."\n\n"; echo crypt($credential, '$2a$05$SomeDollarSalt9999$999')."\n"; echo BF_crypt_with_legacy_salt($credential, '$2a$05$SomeDollarSalt9999$999')."\n\n";
Output for 8.0.28 - 8.0.30, 8.1.16 - 8.1.33, 8.2.3 - 8.2.29, 8.3.0 - 8.3.25, 8.4.1 - 8.4.12
*0 $2a$05$SomeDollarSalt9999999.hm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e *0 $2a$05$SomeDollarSalt999999$uhm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e *0 $2a$05$SomeDollarSalt99999$9uGElX9NYrj.R45tRnH.xGf936EuwfQ8W *0 $2a$05$SomeDollarSalt9999$99uqedqg9AH7TRnGTjNVhwYkmNJOSW5DpC
Output for 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.27, 8.1.0 - 8.1.15, 8.2.0 - 8.2.2
$2a$05$SomeDollarSalt9999999.hm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e $2a$05$SomeDollarSalt9999999.hm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e $2a$05$SomeDollarSalt999999$uhm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e $2a$05$SomeDollarSalt999999$uhm2CRfKZ6A8x3vd6BRDTNlN3DDJPW3e $2a$05$SomeDollarSalt99999$9uGElX9NYrj.R45tRnH.xGf936EuwfQ8W $2a$05$SomeDollarSalt99999$9uGElX9NYrj.R45tRnH.xGf936EuwfQ8W $2a$05$SomeDollarSalt9999$99uqedqg9AH7TRnGTjNVhwYkmNJOSW5DpC $2a$05$SomeDollarSalt9999$99uqedqg9AH7TRnGTjNVhwYkmNJOSW5DpC
Output for 4.3.0 - 4.3.11, 4.4.0 - 4.4.9, 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17

Process exited with code 139.

preferences:
111.39 ms | 410 KiB | 5 Q