Skip to content

Instantly share code, notes, and snippets.

@ziadoz ziadoz/BCrypt.php
Created Jul 30, 2012

Embed
What would you like to do?
A Lightweight PHP BCrypt Class
<?php
class BCrypt
{
/**
* Work factor cost boundaries and default.
*
* @var const
*/
const COST_MIN = 4;
const COST_MAX = 31;
const COST_DEFAULT = 12;
/**
* Generate a BCrypt salt.
*
* @param $salt An optional custom salt.
* @return string
*/
public static function salt($salt = null)
{
if (null !== $salt) {
$salt = base64_encode(sha1($salt));
} elseif (function_exists('openssl_random_pseudo_bytes')) {
$salt = base64_encode(openssl_random_pseudo_bytes(16));
} else {
mt_srand();
$salt = base64_encode(sha1(mt_rand() . uniqid() . time()));
}
return substr(strtr($salt, '+', '.'), 0, 22);
}
/**
* Hash a password using BCrypt.
*
* @param $password The password to hash.
* @param $cost The cost parameter. Must between 04 - 31. Default is 12.
* @param $salt An optional custom salt.
* @return string
*/
public static function hash($password, $cost = self::COST_DEFAULT, $salt = null)
{
if (! is_int($cost)) {
throw new \InvalidArgumentException('Work factor cost parameter must be an integer.');
}
if ($cost < self::COST_MIN) {
$cost = self::COST_MIN;
} elseif ($cost > self::COST_MAX) {
$cost = self::COST_MAX;
}
$salt = (string) self::salt($salt);
$cost = (string) str_pad($cost, 2, '0', STR_PAD_LEFT);
return crypt($password, '$2a$' . $cost . '$' . $salt . '$');
}
/**
* Compare a password to a hash.
*
* @param $password The password to compare.
* @param $hash The password hash to compare.
* @return boolean
*/
public static function compare($password, $hash)
{
return ($hash === crypt($password, $hash));
}
}
<?php
$hash = BCrypt::hash('password');
$valid = BCrypt::compare('password', $hash);
echo ($valid ? 'Yes' : 'No');
@CHH

This comment has been minimized.

Copy link

commented Jul 31, 2012

Wouldn't it be better, if the cost factor would be set to 31 when the user passes something > 31? When the user passes something greater than 31, it's almost sure by accident, but I think he shouldn't get a weaker password for that.

@ziadoz

This comment has been minimized.

Copy link
Owner Author

commented Jul 31, 2012

Good point. I've adjusted the code so it'll use the maximum or minimum cost if you are above or below the boundary.

@ziadoz

This comment has been minimized.

Copy link
Owner Author

commented Aug 13, 2012

I've made this into a simple package and put it on Packagist: https://bitbucket.org/ziadoz/bcrypt

@ziadoz

This comment has been minimized.

Copy link
Owner Author

commented Aug 21, 2014

This code is old and outdated. You should use the native PHP password API or Anthony Ferrara's PasswordCompat library instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.