public void TestPrimeChecker(IPrimeChecker primeChecker) { if (primeChecker.Prime(1)) { Assert.Fail("PrimeChecker claims 1 is a prime"); } for (int p = 2; p < 10000; p++) { bool isPrime = primeChecker.Prime(p); int c = -1; for (int i = 2; i < p; i++) { if (p % i == 0) { c = i; } } if (isPrime && c != -1) { Assert.Fail("PrimeChecker claimed it's prime, but " + c.ToString() + " divides " + p.ToString(), p, c); } else if (c == -1 && !isPrime) { Assert.Fail("PrimeChecker claimed it's composite, but we didn't find any divisor", p); } } }
long FindDivisor(long n) { if (PrimeChecker.Prime(n)) { throw new Exception("Number is already prime, can't find any nontrivial divisor."); } if ((n & 1) == 0) { return(2); } var rt = FindRoot(n); if (rt != -1) { return(rt); } while (true) { long a = (MathUtils.Random() % (n - 1)) + 1; long g = MathUtils.GCD(n, a); if (g != 1) { return(g); } long r = OrderFinder.Find(a, n); if ((r & 1) != 0) { continue; } if (MathUtils.FastPowMod(a, r / 2, n) == n - 1) { continue; } long DivShare = MathUtils.FastPowMod(a, r / 2, n) - 1; return(MathUtils.GCD(n, DivShare)); } }