<?php
class Blowfish
{
    public $cypher = 'blowfish';
    public $mode   = 'cfb';
    public $key    = '12345678';

    public function __construct($options = array()) {

        $this->cypher = isset($options["cypher"]) ? $options["cypher"] : $this->cypher;
        $this->mode = isset($options["mode"]) ? $options["mode"] : $this->mode;
        $this->key = isset($options["key"]) ? $options["key"] : $this->key;
    }

    public function encrypt($plaintext)
    {
        $td = mcrypt_module_open($this->cypher, '', $this->mode, '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $this->key, $iv);
        $crypttext = mcrypt_generic($td, $plaintext);
        mcrypt_generic_deinit($td);
        return $iv.$crypttext;
    }

    public function decrypt($crypttext)
    {
        $plaintext = "";
        $td        = mcrypt_module_open($this->cypher, '', $this->mode, '');
        $ivsize    = mcrypt_enc_get_iv_size($td);
        $iv        = substr($crypttext, 0, $ivsize);
        $crypttext = substr($crypttext, $ivsize);
        if ($iv)
        {
            mcrypt_generic_init($td, $this->key, $iv);
            $plaintext = mdecrypt_generic($td, $crypttext);
        }
        return $plaintext;
    }
}

/***************************************************************************
 ********************************* Utilities *******************************
 ***************************************************************************/

function cryptToken($pass, $salt = '') {

    $salt = ($salt=='') ? random_string('alnum', 8) : $salt;
    return (crypt($pass, '$1$' . $salt . '$'));
}

function checkToken($pass, $cryptPassw) {

    if (!isset($cryptPassw)) return false;

    list(,, $salt, $unsalted) = explode('$', $pass);

    return ($cryptPasswd == cryptToken($pass, $salt));
}

function random_string($type = 'alnum', $len = 8)
{
    switch ($type)
    {
        case 'alpha'    :   $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
        case 'alnum'    :   $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
        case 'numeric'  :   $pool = '0123456789';
            break;
        case 'nozero'   :   $pool = '123456789';
            break;
    }

    $str = '';
    for ($i=0; $i < $len; $i++)
    {
        $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
    }
    return $str;
}
