<?php
/**
 * Clase para encriptar o desincriptar cadenas 
 * @fecha   03/07/2013
 * @author  Hector Velasco
 */
class EncryptClass
{
    var $iv = "";
    
   
    function EncryptClass($iv="827861bf781ff753786SDEXb8m8VCnh0A1")
    {
        $this->iv = $iv;
    }
    
    
    /**
     * Encripta o desencripta cadenas de pendiendo del parametro $crypt
     * @param type $text
     * @param type $key
     * @param type $alg algoritmo
     * @param type $crypt 1->encriptar 0->desencriptar
     * @return type 
     */
    function encripta($text, $key, $alg, $crypt=1)
    {
        $encrypted_data="";
        $pad = true;
        
        if(strlen($key) > 32)
        {
           $key = substr($key,0,32);
        }
        
        switch($alg)
        {
            case "3des":
                $td = mcrypt_module_open('tripledes', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "cast-128":
                $td = mcrypt_module_open('cast-128', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;   
            case "gost":
                $td = mcrypt_module_open('gost', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;   
            case "rijndael-128":
                
                $td = mcrypt_module_open('rijndael-128', '', 'cbc', $this->getIVLength(16));
                mcrypt_generic_init($td, $key, $this->getIVLength(16));
                $pad = false;
            break;       
            case "twofish":
               
                $td = mcrypt_module_open('twofish', '', 'cbc', $this->getIVLength(16));
                mcrypt_generic_init($td, $key, $this->getIVLength(16));
                $pad = false;
            break;   
            case "arcfour":
                $td = mcrypt_module_open('arcfour', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "cast-256":
                $td = mcrypt_module_open('cast-256', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;   
            case "loki97":
                
                $td = mcrypt_module_open('loki97', '', 'cbc', $this->getIVLength(16));
                mcrypt_generic_init($td, $key, $this->getIVLength(16));
                $pad = false;
            break;       
            case "rijndael-192":
                $td = mcrypt_module_open('rijndael-192', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "saferplus":
                $td = mcrypt_module_open('saferplus', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "wake":
                $td = mcrypt_module_open('wake', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "blowfish-compat":
                $td = mcrypt_module_open('blowfish-compat', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "des":
                $td = mcrypt_module_open('des', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "rijndael-256":
                $td = mcrypt_module_open('rijndael-256', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
                $pad = false;
            break;
            case "xtea":
                $td = mcrypt_module_open('xtea', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "enigma":
                $td = mcrypt_module_open('enigma', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;
            case "rc2":
                $td = mcrypt_module_open('rc2', '', 'cbc', $this->iv);
                mcrypt_generic_init($td, $key, $this->iv);
            break;   
            case "blowfish":
                $td = mcrypt_module_open('blowfish', '', 'cbc', $this->getIVLength(8));
                mcrypt_generic_init($td, $key, $this->getIVLength(8));
            break;
            default:
                $td = mcrypt_module_open('blowfish', '', 'cbc', $this->getIVLength(8));
                
                mcrypt_generic_init($td, $key, $this->getIVLength(8));
            break;                                           
        }

        if($crypt == 1)
        {
            $encrypted_data = base64_encode(mcrypt_generic($td, $this->pkcs5_pad($text)));
        }
        else
        {
            if($pad)
            {
                $encrypted_data = $this->pkcs5_unpad(mdecrypt_generic($td, base64_decode($text)));
            }
            else
            {
                 $encrypted_data = mdecrypt_generic($td, base64_decode($text));
                 $encrypted_data = preg_replace( "/\p{Cc}*$/u", "", $encrypted_data);
            }
        }

        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        
       
        
        return $encrypted_data;
    }
    
    /**
     * Desencripta cadenas
     * @param type $text
     * @param type $key
     * @param type $alg algoritmo
     * @return type 
     */
    function desencripta($text, $key, $alg)
    {
        return $this->encripta($text, $key, $alg, 0);
    }
    
    /**
     * Obtiene la llave primaria de la longitud requerida
     * @param type $len
     * @return type
     */
    private function getIVLength($len)
    {
        $iv = "";
        if(strlen($this->iv) > $len)
        {
           $iv = substr($this->iv,0,$len);
        }
        else{
             $iv = $this->iv;
        }
        
        return $iv;
    }
	
    function pkcs5_pad ($text) 
    { 
        $blocksize = 8;
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    function pkcs5_unpad($text)
    {
        $pad = ord($text{strlen($text)-1});
        if ($pad > strlen($text))
        {
            return false;
        }
        
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
        {
            return false;
        }

        return substr($text, 0, -1 * $pad);
    }
    
}