* @link http://www.omegapages.com */ /** * URL Encoder class * @package get_crypt * @author Jason Browatzke * @link http://www.omegapages.com */ class get_crypt{ // Advanced options /** * Conversion Base * Base is used as a conversion bases from a hexidecimal number to what ever number base you want (between 2 and 36) * @var integer Conversion base 2 - 36 16=no change */ var $base = 25; /** * Key length * They Key length is used in determining the length of te key used for the tamper testing value * @var integer Length of key (when added to keylen must be equalto or less than 32) */ var $keyLen = 5; /** * Key offset * They Key offset is used in determining the position of the beginning of the key used in the tamper testing value * The key is generated using a md5 hash of the key supplied in the {@link get_crypt::get_crypt() CONSTRUCTOR} * @var integer Offset of md5 string at whick the key is grabbed */ var $keyOffset = 5; /** * @var bool Turns on or off debugging */ var $debug = false; /** * @access private */ var $key_key = ''; /** * @access private */ var $key = ''; /** * @access private */ var $string_data = ''; /** * @access private */ var $enc_data = ''; /** * @access private */ var $chop = 2; /** * @access private */ var $out = ''; //*************************************************************************************// //************************ Main functions ***************************// //*************************************************************************************// /** * Constructor * * Initializes our key and our chop values * @uses get_crypt::set_key() Sets the key * @uses get_crypt::set_chop() Sets the chop value * @see get_crypt::set_key(), get_crypt::set_chop() * @param string $key_key optional If left blank will use current date * @return void */ function get_crypt($key_key = null){ if ($key_key!==null){ $this->key_key = $key_key; }else{ $this->key_key = date('YmdH'); } $this->set_key(); $this->set_chop(); } /** * Encoding function * * Accepts variables in an aray and returns encoded values in a string * @uses get_crypt::debug() Sends debug information to the screen * @uses get_crypt::make_url() Urlencodes the array into a string * @uses get_crypt::obscufate_data() Encodes the data into a string * @uses get_crypt::add_salt() Adds tamper testing values to the encoded string * @see get_crypt::debug(), get_crypt::make_url(), get_crypt::obscufate_data(), get_crypt::add_salt() * @param array $vars Array of named variables * @return string */ function encode($vars){ $this->debug($vars,__LINE__,'Input array'); $this->string_data = $this->make_url($vars); $this->debug($this->string_data,__LINE__,'Url encoded data'); $this->enc_data = $this->obscufate_data(); $this->debug($this->enc_data,__LINE__,'Encoded data'); $this->out = $this->add_salt(); $this->debug($this->out,__LINE__,'Salted data'); return $this->out; } /** * Decoding function * * Accepts encoded string value and returns decoded array value * @uses get_crypt::debug() Sends debug information to the screen * @uses get_crypt::verify_salt() Tests to make sure no tampering has taken place * @uses get_crypt::strip_salt() Removes the tamper testing values from the encoded string * @uses get_crypt::deobscufate_data() Decodes stings into url encoded data * @uses get_crypt::populate_var() Decodes url encoded data into a named array * @see get_crypt::debug(), get_crypt::verify_salt(), get_crypt::strip_salt(), get_crypt::deobscufate_data(),get_crypt::populate_var() * @param string $str String of encoded data * @return array */ function decode($str){ $this->enc_data = $str; $this->debug($this->enc_data,__LINE__,'Encoded data'); if ($this->verify_salt()===true){ $this->enc_data = $this->strip_salt(); $this->debug($this->enc_data,__LINE__,'Saltless data'); $this->string_data = $this->deobscufate_data(); $this->debug($this->string_data,__LINE__,'Url encoded data'); $this->out = $this->populate_var(); $this->debug($this->out,__LINE__,'Output array'); return $this->out; }else{ return false; } } //*************************************************************************************// //************************ Main functions ***************************// //*************************************************************************************// /** * Sets tamper testing key * * Accepts nothing and returns nothing called from {@link get_crypt::encode()} * @uses get_crypt::debug() Sends debug information to the screen * @see get_crypt::debug() * @uses get_crypt::keylen * @param void * @return void */ function set_key(){ if ($this->keyLen + $this->keyOffset>32){ $this->keyOffset = 5; $this->keyLen = 5; } $this->key = substr(md5($this->key_key),$this->keyOffset,$this->keyLen); $this->debug($this->key,__LINE__,'Key'); } /** * Sets chop value * * Sets the chop value used internally for encoding and decoding purposes * The chop value is derived from the length of the base converted value 255 * @uses get_crypt::debug() Sends debug information to the screen * @see get_crypt::debug(), get_crypt::base, get_crypt::chop * @param void * @return void */ function set_chop(){ $this->chop = strlen(strval(base_convert(255,10,$this->base))); $this->debug("$this->chop",__LINE__,'Chop'); } /** * Creates url encoded variable * * Accepts a named array of strings and returns a urlencoded version of the array * called from {@link get_crypt::encode()} * @see get_crypt::base * @param array $vars array of named strings * @return string */ function make_url($vars){ $str = ''; foreach($vars as $name => $val){ if ($str===''){ $str .= "$name=".urlencode($val); }else{ $str .= "&$name=".urlencode($val); } } return $str; } /** * Adds zeros infront of strings too short * * Prepends zeros to strings that are not as long as the chop value * called from {@link get_crypt::obscufate_data()} * @see get_crypt::obscufate_data(), get_crypt::set_chop() * @param string $str * @return string */ function leading_zero($str){ while (strlen($str)<$this->chop){ $str = '0'.$str; } return $str; } /** * Encodes data using the base value * * Accepts a named array of strings and returns a urlencoded version of the array * called from {@link get_crypt::encode()} * @see get_crypt::base, get_crypt::encode() * @uses get_crypt::base * @param void * @return string */ function obscufate_data(){ $len = strlen($this->string_data); $out = ''; for($i=0;$i < $len;$i++){ // iterate through the string $out .= $this->leading_zero(strval(base_convert(dechex(ord($this->string_data{$i})),16,$this->base))); // convet the base of the hex value of the ordinal value of the char to base 17 encode as a string and append to the output string; } return $out; } /** * Adds tamper protection string to encoded data * * Accepts nothing and returns the final product of {@link get_crypt::encode()} * called from {@link get_crypt::encode()} * @see get_crypt::encode(), get_crypt::keylen * @uses get_crypt::keylen * @param void * @return string */ function add_salt(){ $len = strlen($this->enc_data); $middle = round($len / 2); $this->debug($middle,__LINE__,'Original middle value'); $len = floor($this->keyLen / 2); $diff = ($this->keyLen - ($len * 2)); $start = substr($this->key,0,$len); $mid = substr($this->key,$len,$diff); $finish = substr($this->key,-$len); $front = substr($this->enc_data,0,$middle); $back = substr($this->enc_data,-$middle); $out = "$start$front$mid$back$finish"; return $out; } /** * Tests tamper protection string to check for tampering * * Accepts nothing and returns true on success false on failure * called from {@link get_crypt::decode()} * @see get_crypt::decode(), get_crypt::keylen * @uses get_crypt::keylen * @param void * @return bool */ function verify_salt(){ $middle = round((strlen($this->enc_data) - $this->keyLen) / 2); $this->debug($middle,__LINE__,'Verify middle value'); $len = floor($this->keyLen / 2); $diff = ($this->keyLen - ($len * 2)); $start = substr($this->key,0,$len); $mid = substr($this->key,$len,$diff); $finish = substr($this->key,($len * -1)); $f = substr($this->enc_data,0,$len); $m = substr($this->enc_data,$middle + $len,$diff); $b = substr($this->enc_data,-$len); return ("$f$m$b" == $this->key); } /** * Removes tamper protection string from encoded data * * Accepts nothing and returns encoded string less the tamper protection string * The {@link get_crypt::set_chop() chop}} value is VERY important here * called from {@link get_crypt::decode()} * @see get_crypt::decode(), get_crypt::set_chop(), get_crypt::keylen * @uses get_crypt::keylen * @param void * @return string */ function strip_salt(){ $len = floor($this->keyLen / 2); $diff = $this->keyLen - (2 * $len); $this->enc_data = substr($this->enc_data,$len); $this->enc_data = substr($this->enc_data,0,-$len); $mid = round(strlen($this->enc_data) / 2) - $diff; $this->debug($mid,__LINE__,'Decode middle value'); $mm = 0; if (fmod(strlen($this->enc_data)-$diff,$this->chop)!=0){ $mm++; } $start = substr($this->enc_data,0,$mid); $finish = substr($this->enc_data,-($mid - $mm)); $out = "$start$finish"; return $out; } /** * Decodes encoded data * * Accepts nothing and returns url encoded string * The {@link get_crypt::set_chop() chop}} value is VERY important here as well as the {@link get_crypt::base base} value * called from {@link get_crypt::decode()} * @see get_crypt::decode(), get_crypt::set_chop(), get_crypt::base * @uses get_crypt::base Uses this value for conversion * @uses get_crypt::chop Uses this value for item seperation * @param void * @return string */ function deobscufate_data(){ $tempdata = wordwrap($this->enc_data,$this->chop,':',1); $temparr = explode(':',$tempdata); $out = ''; foreach($temparr as $val){ $out.= chr(hexdec(base_convert($val,$this->base,16))); } return $out; } /** * Populates an array by decoding the url encoded data * * Accepts nothing and returns an array containing decoded values * called from {@link get_crypt::decode()} * @see get_crypt::decode() * @param void * @return array */ function populate_var(){ $arr = explode('&',$this->string_data); $out = array(); foreach($arr as $val){ @list($name,$value) = @explode('=',$val); $out[$name]=urldecode($value); } return $out; } /** * Output debug information * * Accepts the data the line number as well as a title * called from {@link get_crypt::decode()} * @param mixed $data String data or array data to output * @param integer $line optional Line number that the debug info came from * @param string $title optional Title for debug line * @return void */ function debug($data,$line = __LINE__,$title = ''){ if ($this->debug){ if (is_array($data)){ echo "Debug - line: $line: $title
";
        print_r($data);
        echo "

"; }else{ echo "Debug - line $line: $title $data
\r\n"; } } } } /** * Test class for {@link get_crypt GET_CRYPT} * * This tester class will iterate through the {@link get_crypt::base bases} of 2 through 36 * while iterating through {@link get_crypt::keyLen KeyLen's} from 5 to 27. This is done 100 times couting time and success ratio * @subpackage test_crypt * @uses get_crypt * @link http://www.omegapages.com */ class test_crypt extends get_crypt{ /** * @access private */ var $test_vals = array(); /** * @access private */ var $testpart1 = ''; /** * @access private */ var $testpart2 = ''; /** * This function counts the seconds between two times * * This function is called from {@link test_crypt::test_crypt() test_crypt::test_crypt} and is used for timing test operations * @param float $start Start time in milliseconds * @return float */ function elapsed($start){ $end = microtime(); list($start2, $start1) = explode(" ", $start); list($end2, $end1) = explode(" ", $end); $diff1 = $end1 - $start1; $diff2 = $end2 - $start2; if ($diff2 < 0 ){ $diff1 -= 1; $diff2 += 1.0; } return $diff2 + $diff1; } /** * This function returns random strings * * This function is called from {@link test_crypt::generate_vals() test_crypt::generate_vals} and is used for creating strings to pupolate an array * @param bool $long Determine wether or not to return a long string * @return string */ function generate_string($long){ ($long) ? $to = 10 : $to = 0; $out = ''; for($i=0;$i<=mt_rand(1+$to,10 + $to);$i++){ $out .= chr(97+mt_rand(0,26)); } return $out; } /** * This function returns an array or random named strings * * This function is called from {@link test_crypt::test_bases() test_crypt::test_bases} and is used for populating an array with values * @uses test_crypt::generate_string() * @param bool $long Determine wether or not to return a long string * @return string */ function generate_vals(){ $array = array(); for($i=0;$i<=mt_rand(1,10);$i++){ $str1 = $this->generate_string(false); $str2 = $this->generate_string(true); $array[$str1]=$str2; } $this->test_vals = $array; } /** * This function detemines if the encoded and decoded values are identical * * This function is called from {@link test_crypt::test_bases() test_crypt::test_bases} testing the input and output values for identicality * @param void * @return void */ function comparevalues(){ return ($this->test_vals===$this->testpart2); } /** * This function is the bulk of the testing here we iterate through the bases 2 through 36 * * This function is called from {@link test_crypt::test_keys() test_crypt::test_keys} and tests the bases between 2 and 36 with the key provided * @uses test_crypt::generate_vals() * @uses get_crypt::set_chop() * @uses get_crypt::encode() * @uses get_crypt::decode() * @see get_crypt::base, test_crypt::generate_vals(), get_crypt::set_chop(), get_crypt::encode(), get_crypt::decode() * @param void * @return void */ function test_bases(){ for($i=2;$i<=36;$i++){ $this->base = $i; $this->set_chop(); $this->generate_vals(); $this->testpart1 = $this->encode($this->test_vals); $this->testpart2 = $this->decode($this->testpart1); if (!$this->comparevalues()){ echo "Failed!"; } } } /** * This function iterates through the {@link get_crypt::keyLen keyLen} between 5 and 27 (keeping {@link get_crypt::keyOffset keyOffset} at 5) * * This function is called from {@link test_crypt::test_crypt() test_crypt::test_crypt} and iterates through {@link get_crypt:keyLen keyLen} betwen 5 and 27 * @uses test_crypt::test_bases() * @uses get_crypt::set_key() * @see get_crypt::keyLen, test_crypt::test_bases(), get_crypt::set_key() * @param void * @return void */ function test_keys(){ for($i=5;$i<=27;$i++){ $this->keyLen = $i; $this->set_key(); $this->test_bases(); } } /** * This is the constructor for this class * * This class initialisez the {@link get_crypt get_crypt} object and then starts iterating the values * @uses get_crypt::get_crypt() * @uses test_crypt::test_keys() * @uses test_crypt::elapsed() * @see get_crypt::debug, test_crypt::elapsed(), get_crypt::get_crypt() * @param void * @return void */ function test_crypt(){ set_time_limit(0); $this->get_crypt(); $this->debug = true; $test_start = microtime(); for($i=1;$i<=100;$i++){ echo "Test $i: "; $start = microtime(); $this->test_keys(); echo "Successful"; $time = round($this->elapsed($start),2); echo " - $time seconds\r\n"; } $time = round($this->elapsed($test_start),2); echo "Total test time:$time seconds\r\n"; } } //$test = new test_crypt(); ?>