问题
I want to run something like below code so that i would be able to find a divisor for numbers of ~30-40 length without having to check millions of possibilities even up to their square root. What is the fastest possible solution to find a legitimate non trivial divisor of a number or how can i improve below code to run faster, without having to loop through all possible options.
static int divisor(string numberToCheck)
{
BigInteger n = BigInteger.Parse(numberToCheck);
BigInteger sqrt = Sqrt(n);
if (n % 2 == 0)
return 2;
for (UInt64 = 3; i <= sqrt; i+=2)
{
if (n % i == 0)
return i;
}
return -1;
}
回答1:
For numbers of 30 to 40 digits, you need a better algorithm than trial division, which has time complexity O(sqrt(n)).
In the mid 1970s, John Pollard invented two algorithms that are small increases in complexity but large increases in power: the rho algorithm and the p-1 algorithm. Both algorithms are O(sqrt(sqrt(n))), and neither is particularly hard to program.
If those algorithms don't work, the next step is to try the elliptic curve method, invented by Hendrik Lenstra in the early 1980s. You will have to work harder to get a decent implementation, but you will be able to find factors up to 30 or 40 digits without too much trouble, and you will certainly be able to split a 40-digit composite.
Google for all those algorithms, or search here on Stack Exchange, or ask specific questions if you don't find what you need. You might also look at my blog, which has implementations of all those algorithms.
回答2:
Factorization of large numbers is hard. So hard that it's the basis for a lot of modern cryptography.
The best factorization algorithms are also complicated, and the easiest option is probably to use a library that someone else has already written. A quick search turned up https://sourceforge.net/projects/msieve/ which is written in C, and can even make use of a GPU to speed up the search.
It uses the General number field sieve (GNFS) algorithm.
回答3:
Let run some numbers
Square root is up to 10^20
If you only do odd then (10^20/2)
Let assume you can do 100,000 / second
10^(20-5)/2 = 10^15/2
10^15/2 seconds = 15,854,896 years
Only processing primes would cut that by a factor of 10
Lets assume you can do a billion a second and only do primes - that gets it down to 0.8 years
This is just not reasonable
At 100,000 / second what could you do in 1 minute?
60,000,000 calcs in one minutes
100,000,000 is 5,761,455 primes
(10^8)^2 = 10^16
Much beyond 10^16 this get unreasonable unless you go after some massive computer power
Why do you need to find a divisor for number that big anyway?
来源:https://stackoverflow.com/questions/36519938/what-is-the-fastest-way-to-find-divisor-of-any-biginteger-in-c-sharp