//FROM SKYPILOT ON STACK OVERFLOW
<?php
class Bcrypt {
private $rounds;
public function __construct($rounds = 12) {
if(CRYPT_BLOWFISH != 1) {
throw new Exception("bcrypt not supported in this installation. See http://php.net/crypt");
}
$this->rounds = $rounds;
}
public function hash($input) {
$hash = crypt($input, $this->getSalt());
if(strlen($hash) > 13)
return $hash;
return false;
}
public function verify($input, $existingHash) {
$hash = crypt($input, $existingHash);
return $hash === $existingHash;
}
private function getSalt() {
$salt = sprintf('$2a$%02d$', $this->rounds);
$bytes = $this->getRandomBytes(16);
$salt .= $this->encodeBytes($bytes);
return $salt;
}
private $randomState;
private function getRandomBytes($count) {
$bytes = '';
if(function_exists('openssl_random_pseudo_bytes') &&
(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL slow on Win
$bytes = openssl_random_pseudo_bytes($count);
}
if($bytes === '' && is_readable('/dev/urandom') &&
($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
$bytes = fread($hRand, $count);
fclose($hRand);
}
if(strlen($bytes) < $count) {
$bytes = '';
if($this->randomState === null) {
$this->randomState = microtime();
if(function_exists('getmypid')) {
$this->randomState .= getmypid();
}
}
for($i = 0; $i < $count; $i += 16) {
$this->randomState = md5(microtime() . $this->randomState);
if (PHP_VERSION >= '5') {
$bytes .= md5($this->randomState, true);
} else {
$bytes .= pack('H*', md5($this->randomState));
}
}
$bytes = substr($bytes, 0, $count);
}
return $bytes;
}
private function encodeBytes($input) {
// The following is code from the PHP Password Hashing Framework
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (1);
return $output;
}
}
class Register
{
// Protect the information from the public.
private $username;
private $password;
private $passmd5;
private $email;
private $mii;
private $vr;
private $character;
private $track;
private $course;
private $kart;
private $wheel;
private $glider;
private $rank;
private $fc;
private $errors;
private $token;
// Tell the server to store the values from the following input field names.
public function __construct()
{
$this->errors = array();
$this->username = $this->filter($_POST['ruser']);
$this->password = $this->filter($_POST['rpass']);
$this->email = $this->filter($_POST['remail']);
$this->mii = $this->filter($_POST['rmii']);
$this->vr = $this->filter($_POST['rvr']);
$this->character = $this->filter($_POST['rcharacter']);
$this->track = $this->filter($_POST['rtrack']);
$this->course = $this->filter($_POST['rcourse']);
$this->kart = $this->filter($_POST['rkart']);
$this->wheel = $this->filter($_POST['rwheel']);
$this->glider = $this->filter($_POST['rglider']);
$this->rank = $this->filter($_POST['rrank']);
$this->fc = $this->filter($_POST['rfc']);
$this->token = $_POST['token'];
// $this->passmd5 = $bcrypt($this->password); Old method, still have for backup purposes.
$bcrypt = new Bcrypt(15);
$hash = $bcrypt->hash($this->password);
$isGood = $bcrypt->verify($this->password, $hash);
}
// Process the information.
public function process()
{
if($this->valid_token() && $this->valid_data())
$this->register();
return count($this->errors)? 0 : 1;
}
public function filter($var)
{
return preg_replace('/[^a-zA-Z0-9@.]/','',$var);
}
// Actually transfer the information from the form to the database.
public function register()
{
mysql_connect("localhost","root","") or die(mysql_error());
mysql_select_db("mk7") or die (mysql_error());
mysql_query("INSERT INTO users(username,password,email,mii,vr,character,track,course,kart,wheel,glider,rank,fc) VALUES ('{$this->username}','{$isGood}','{$this->email}','{$this->mii}','{$this->vr}','{$this->character}','{$this->track}','{$this->course}','{$this->kart}','{$this->wheel}','{$this->rank}','{$this->fc}')");
if(mysql_affected_rows()< 1)
$this->errors[] = '• Could not process form.';
}
// Insert an ID based off of the username, and check to see if the user already exists.
public function user_exists()
{
mysql_connect("localhost","root","") or die(mysql_error());
mysql_select_db("mk7") or die (mysql_error());
$data = mysql_query("SELECT ID FROM users WHERE username = '{$this->username}'");
return mysql_num_rows($data)? 1 : 0;
}
// Show the errors.
public function show_errors()
{
echo "<h3>Errors</h3>";
foreach($this->errors as $key=>$value)
echo $value."<br>";
}
// Errors to show.
public function valid_data()
{
if($this->user_exists())
$this->errors[] = '• Username already taken.';
if(empty($this->username))
$this->errors[] = '• Invalid username.';
if(empty($this->password))
$this->errors[] = '• Invalid password.';
if(empty($this->email) || !preg_match('/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/',$this->email))
$this->errors[] = '• Invalid email.';
return count($this->errors)? 0 : 1;
}
// If everything is okay go through with the form.
public function valid_token()
{
if(!isset($_SESSION['token']) || $this->token != $_SESSION['token'])
$this->errors[] = '• Invalid submission.';
return count($this->errors)? 0 : 1;
}
}
?>