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'; } } ?>