Fermat’s Factorization method for large numbers

Given a large number N, the task is to divide this number into a product of two factors, using Fermat’s Factorisation method.

Examples

Input: N = 105327569
Output: 10223, 10303

Input: N = 249803
Output: 23, 10861

Fermat Factorization: Fermat’s Factorization method is based on the representation of an odd integer as the difference of two squares.
For an integer N, we want a and b such as:



N = a2 - b2 = (a+b)(a-b) 

where (a+b) and (a-b) are 
the factors of the number N.

Approach:

  1. Get the number as an object of BigInteger class
  2. Find the square root of N.
  3. It is guaranteed that the value of a is greater than sqrt(N) and value of b less than sqrt(N).
  4. Take the value of sqrt(n) as a and increment the number until and unless a number b is found such that N – a^2 is a perfect square.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for Fermat's Factorization
// method for large numbers
  
import java.math.*;
import java.util.*;
  
class Solution {
  
    // Function to find the Floor
    // of square root of a number
    public static BigInteger sqrtF(BigInteger x)
        throws IllegalArgumentException
    {
        // if x is less than 0
        if (x.compareTo(BigInteger.ZERO) < 0) {
            throw new IllegalArgumentException(
                "Negative argument.");
        }
  
        // if x==0 or x==1
        if (x.equals(BigInteger.ZERO)
            || x.equals(BigInteger.ONE)) {
            return x;
        }
  
        BigInteger two
            = BigInteger.valueOf(2L);
        BigInteger y;
  
        // run a loop
        y = x.divide(two);
        while (y.compareTo(x.divide(y)) > 0)
            y = ((x.divide(y)).add(y))
                    .divide(two);
        return y;
    }
  
    // function to find the Ceil
    // of square root of a number
    public static BigInteger sqrtC(BigInteger x)
        throws IllegalArgumentException
    {
        BigInteger y = sqrtF(x);
  
        if (x.compareTo(y.multiply(y)) == 0) {
            return y;
        }
  
        else {
            return y.add(BigInteger.ONE);
        }
    }
  
    // Fermat factorisation
    static String FermatFactors(BigInteger n)
    {
        // constants
        BigInteger ONE = new BigInteger("1");
        BigInteger ZERO = new BigInteger("0");
        BigInteger TWO = new BigInteger("2");
  
        // if n%2 ==0 then return the factors
        if (n.mod(TWO).equals(ZERO)) {
            return n.divide(TWO)
                       .toString()
                + ", 2";
        }
  
        // find the square root
        BigInteger a = sqrtC(n);
  
        // if the number is a perfect square
        if (a.multiply(a).equals(n)) {
            return a.toString()
                + ", " + a.toString();
        }
  
        // else perform factorisation
        BigInteger b;
        while (true) {
            BigInteger b1 = a.multiply(a)
                                .subtract(n);
            b = sqrtF(b1);
  
            if (b.multiply(b).equals(b1))
                break;
            else
                a = a.add(ONE);
        }
  
        return a.subtract(b).toString()
            + ", " + a.add(b).toString();
    }
  
    // Driver code
    public static void main(String args[])
    {
        String N = "105327569";
  
        System.out.println(
            FermatFactors(
                new BigInteger(N)));
    }
}

chevron_right


Output:

10223, 10303

Performance Analysis:

  • Time Complexity: O(sqrt(N))
  • Space Complexity: O(1)

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.