$p) { $out[$i] = $input[$p-1]; } return $out; } /** * Exclusive OR two arrays * @param * @param * @return */ function Crypto_XOR ($a, $b) { foreach ($a as $i => $x) { $out[$i] = abs($a[$i] - $b[$i]); } return $out; } /** * Convert a binary number it its decimal value * @param Array of Integer $a Binary value as array * @return Integer Decimal value */ function Crypto_BinArr2Dec($a) { $i = 0; $b = 0; foreach (array_reverse($a) as $x) { $b = $b + ($x * pow(2,$i)); $i++; } return $b; } /** * Convert decimal number into its n bit binary value stored in an Array * @param Integer $a Decimal integer * @param Integer $n Number of bits * @return Array of Integer Binary value */ function Crypto_Dec2BinArr($a,$n) { if ($a >= pow(2,$n)) { echo 'Error in Crypto_Dec2BinArr(): $a must be less than 2^$n.'; return array(); } $b = array(); $i = 0; if ($a == 0) { $b = array_pad($b,$n,0); } while ($a != 0 && $i < $n) { $b[] = $a % 2; $a = $a / 2; $i++; } return array_reverse($b); } /** * Converts an ASCII string into its binary equivalent, that is * 7-bits for each character * @param String $ascii text or words * @param Integer $bits Number of bits the character is converted to (Default: 7) * @return String binary representation of input text or words */ function Crypto_ASCII2BinString ($ascii,$bits=7) { $l = strlen($ascii); $bin = ''; for ($i = 0; $i < $l; $i++) { $bin_arr = Crypto_Dec2BinArr(ord($ascii[$i]),$bits); $bin = $bin . implode("",$bin_arr); } return $bin; } /** * Converts binary data into string of Hexadecimal digits * @param String $bin binary representation of text * @return String text */ function Crypto_BinString2Hex ($bin) { $l = floor(strlen($bin) / 4); $hex = ''; for ($i = 0; $i < $l; $i++) { $hex = $hex . base_convert(substr($bin,$i*4,4),2,16); } return $hex; } /** * Converts an Hex string into its binary equivalent * @param String $hex Hex * @return String binary representation of input hex */ function Crypto_Hex2BinString ($hex) { $l = strlen($hex); $bin = ''; for ($i = 0; $i < $l; $i++) { $bin = $bin . str_pad(base_convert(substr($hex,$i,1),16,2),4,"0",STR_PAD_LEFT); } return $bin; } /** * Converts binary data into ASCII (7-bit) text * @param String $bin binary representation of text * @param Integer $bits Number of bits to convert to character (Default: 7) * @return String text */ function Crypto_BinString2ASCII ($bin,$bits=7) { $l = floor(strlen($bin) / $bits); $ascii = ''; for ($i = 0; $i < $l; $i++) { $bin_arr = str_split(substr($bin,$i*$bits,$bits)); $dec = Crypto_BinArr2Dec($bin_arr); // if ($dec < 32 || $dec > 122) { if ($dec < 0 || $dec > 127) { $ascii = $ascii . "~"; } else { $ascii = $ascii . chr($dec); } } return $ascii; } function Sec_IsPrime($n) { /* Returns true of $n is a prime number * Code from http://www.phpmath.com/ */ $sqrtn = sqrt($n); for($i=2; $i <= $sqrtn; $i++ ) if ($n % $i == 0) return false; return true ; } function Sec_ListPrimes($upTo) { /* Return the prime numbers up to the parameter $upTo * Code from http://www.phpmath.com/ */ if ($upTo > 0) { $size = $upTo + 1; $flags = array(); $primes = array(); $limit = sqrt($size); // Set flags for ($i=2; $i < $size; $i++) $flags[$i] = true; // Cross out multiples of 2 $j = 2; for ($i=$j+$j; $i < $size; $i=$i+$j) $flags[$i] = false; // Cross out multiples of odd numbers for ($j=3; $j <= $limit; $j=$j+2) { if ($flags[$j]) { for ($i=$j+$j; $i < $size; $i=$i+$j) $flags[$i] = false; } } // Build list of primes from what is left for ($i=2; $i < $size; $i++) { if ($flags[$i]) $primes[] = $i; } return $primes; } else die("n must be greater than 0."); } function Sec_GetPrimeFactors($n,$max=500000) { /* Return the prime factors of $n * $max is an optional parameter, limiting the search * If $max is not given as an input, then the default is used * Code from http://www.phpmath.com/ */ $sqrtn = (int)ceil(sqrt($max)); $trialDivisors = Sec_ListPrimes($sqrtn); $trialDivisors[] = $sqrtn; $factors = array(); if ($n > 0) { if ($n > $max) die("Illegal arguments: ".$n." > ".$max); $k = 0; while ($n > 1) { $divisor = $trialDivisors[$k]; $quotient = $n / $divisor; $remainder = $n % $divisor; if ($remainder == 0) { $factors[] = $divisor; $n = $quotient; } else { if ($quotient > $divisor) $k++; else { $factors[]=$n; break; } } } return $factors; } else die("n must be greater than 0."); } function Sec_Gcd($a,$b) { /* Returns an array with the first entry $x[0] containing the GCD of $a and $b * and the second entry $x[1] containing the multiplicative inverse of $b in mod $a * Uses the function Sec_EuclidGcd to peform the main calculation */ $x = Sec_EuclidGcd($a,$b); if ($x[1] < 0) { if ($a > $b) $x[1] = $a + $x[1]; else $x[1] = $b + $x[1]; } return $x; } function Sec_EuclidGcd($a,$b,$x=0,$y=1) { /* * Calculates the GCD and Multiplicative Inverse (if exists) * Code from http://www.ultimatespin.com/e_art_example.php * Modified to simplify the input parameters */ // ensure that a > b, we can do this because the same two numbers always // have the same gcd. if($a < $b) { Sec_Swap($x,$y); Sec_Swap($a,$b); } //get the m of a/b = mb+r if($a != 0 && $b != 0) { $q = (int)($a/$b); } else { $q = 0; } //if there is no multiplicative inverse if(0 == $b) return array($a,'no inverse'); //if there is a multiplicative invers elseif(1 == $b) return array($b,$y); //otherwise we are not at the gcd so we keep going else return Sec_EuclidGcd($b,($a - ($q * $b)),$y,($x - ($q * $y))); } function Sec_Swap(&$a,&$b) { /* Swaps the two values $a and $b */ $temp = $a; $a = $b; $b = $temp; } function Sec_RelativelyPrime($a,$limit=100000) { /* Returns a list of numbers relatively prime to $a * The list is limited to $limit numbers */ $relprime = array(1); $i = 2; $n = 1; while ($n < $limit and $i < $a) { $x = Sec_Gcd($a,$i); if ($x[0] == 1) { $relprime[] = $i; $n++; } $i++; } return $relprime; } function Sec_Totient($a) { /* Returns Eulers Totient of $a (if it is known) */ $limit = 100000; if (Sec_IsPrime($a)) return $a-1; else { $relprime = Sec_RelativelyPrime($a,$limit); if (count($relprime) < $limit) return count($relprime); else return 'unknown'; } } ?>