<?
Class BritCrypt{
	private $key 					= null;
	private $encodingIn 	= 'UTF-8';
	private $encodingOut 	= 'CP866';
	private $stb					= 63;
	var $type 						= 'default';
	
	public function __construct($key){
	    $this->key = $key;
	}
	
	function encrypt($string=''){       
		switch($this->type){
			case 'lite':
				return $this->crypt_lite($string);
			break;
			case 'reinforced':
		    $seed = '';
		    for ($i = 0; $i < strlen($this->key); $i++) {
		        $seed .= chr(mt_rand(0, 255));
		    }
		    $string ^= $this->gamma($seed, strlen($string));
		    return ($seed ^ $this->key) . $string;
			break;
			default:
				$keyw = $this->calculateKeyw($string);
				$Len = mb_strlen($string, $this->encodingIn);
				$result = '';
		    for ($i = 0; $i < $Len; $i++) {
			    $char = mb_substr($string, $i, 1, $this->encodingIn);
			    $ord = ord(iconv($this->encodingIn, $this->encodingOut, $char));
			    $char = chr(($ord - $this->stb) ^ $keyw[$i]);   
			    $result.= iconv($this->encodingOut, $this->encodingIn, $char);
		    }
				return $result;
			break;
		}
	}
	
	function decrypt($string=''){
		switch($this->type){
			case 'lite':
				return $this->crypt_lite($string);
			break;
			case 'reinforced':
		    $keyLen = strlen($this->key);
		    $seed = substr($string, 0, $keyLen) ^ $this->key;
		    $string = substr($string, $keyLen);
		    $string ^= $this->gamma($seed, strlen($string));
		    return $string;
			break;
			default:
				$keyw = $this->calculateKeyw($string);
				$Len = mb_strlen($string, $this->encodingIn);
				$result = '';
				for ($i = 0; $i < $Len; $i++) {
					$char = mb_substr($string, $i, 1, $this->encodingIn);
					$ord = ord(iconv($this->encodingIn, $this->encodingOut, $char));
					$ord = $ord ^ $keyw[$i];
					$result .=iconv($this->encodingOut, $this->encodingIn, chr($ord + $this->stb));
				}      
				
				return $result;
			break;
		}
	}
	
	function gamma($seed, $len) {
	    $t = '';
	    $count = ceil($len / 20);
	    for ($i = 0; $i < $count; $i++) {
	        $t.= sha1($seed . pack('N', $i), true);
	    }
	    return substr($t, 0, $len);
	}
	
  private function calculateKeyw($pass){
	    $keyw = array();
	    $lenPass = mb_strlen($pass, $this->encodingIn);
	    $lenKey = mb_strlen($this->key, $this->encodingIn);
	    for ($i = 1; $i <= $lenPass; $i++) {
	        if ($lenKey < $lenPass) {
	            $j = $i % $lenKey;
	            if ($j === 0) {
	                $j = $lenKey;
	            }
	        } else {
	            $j = $i;
	        }
	
	        $keyw[] = ord(mb_substr($this->key, $j - 1, 1, $this->encodingIn));
	    }
	    return $keyw;
  }
  
	function crypt_lite($string){
		for($i=0;$i<mb_strlen($string,'utf-8');){
			for($j=0;$j<mb_strlen($this->key,'utf-8');$j++, $i++){
				$outText .= $string{$i} ^ $this->key{$j};
			}
		}
		return $outText;
	}
  
}
?>