static function Hash($data, $rounds, $mintime) { $data = (string) $data; if ($data == "") { return array("success" => false, "error" => "No data."); } // Expand data. $origdata = $data; while (strlen($data) < 56) { $data .= $origdata; } $maxpos = strlen($data); $data .= $data; // Run through Blowfish. $result = ""; for ($x = 0; $x < 32; $x++) { $result .= chr($x); } $x = 0; $ts = microtime(true) + $mintime / 1000; $totalrounds = 0; if (self::IsMcryptAvailable()) { $mp = mcrypt_module_open(MCRYPT_BLOWFISH, "", MCRYPT_MODE_ECB, ""); $iv = str_repeat("", mcrypt_enc_get_iv_size($mp)); if (mcrypt_enc_get_key_size($mp) != 56) { return array("success" => false, "error" => "Unexpected response from PHP function."); } while ($rounds > 0) { $key = substr($data, $x, 56); $x = ($x + 56) % $maxpos; mcrypt_generic_init($mp, $key, $iv); $result = mcrypt_generic($mp, $result); mcrypt_generic_deinit($mp); $result = substr($result, -1) . substr($result, 0, -1); $rounds--; $totalrounds++; if (!$rounds && $mintime > 0 && microtime(true) < $ts) { $rounds++; } } mcrypt_module_close($mp); } else { $numbits = 56 * 8; $bf = new Blowfish(); while ($rounds > 0) { $key = substr($data, $x, 56); $x = ($x + 56) % $maxpos; $bf->SetKey($key, $numbits); $bf->AddData($result); $bf->Finalize(); $result = $bf->Encrypt(); $result = substr($result, -1) . substr($result, 0, -1); $rounds--; $totalrounds++; if (!$rounds && $mintime > 0 && microtime(true) < $ts) { $rounds++; } } } return array("success" => true, "hash" => $result, "rounds" => $totalrounds); }