Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Fermat’s Factorization method for large numbers

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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: 

Java




// 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)));
    }
}

Python3




import math
 
# Function to find the Floor
# of square root of a number
def sqrtF(x):
    # if x is less than 0
    if x < 0:
        raise ValueError("Negative argument.")
     
    # if x==0 or x==1
    if x == 0 or x == 1:
        return x
     
    y = x // 2
     
    # run a loop
    while y > x // y:
        y = (x // y + y) // 2
     
    return y
 
# function to find the Ceil
# of square root of a number
def sqrtC(x):
    y = sqrtF(x)
 
    if x == y * y:
        return y
    else:
        return y + 1
 
# Fermat factorisation
def FermatFactors(n):
    # if n%2 ==0 then return the factors
    if n % 2 == 0:
        return str(n // 2) + ", 2"
     
    # find the square root
    a = sqrtC(n)
     
    # if the number is a perfect square
    if a * a == n:
        return str(a) + ", " + str(a)
     
    # else perform factorisation
    while True:
        b1 = a * a - n
        b = sqrtF(b1)
         
        if b * b == b1:
            break
        else:
            a += 1
     
    return str(a - b) + ", " + str(a + b)
 
# Driver code
if __name__ == "__main__":
    N = "105327569"
 
    print(FermatFactors(int(N)))
# This code is contributed by sarojmcy2e

Javascript




function sqrtF(x) {
  if (x < 0) {
    throw new Error("Negative argument.");
  }
 
  if (x === 0 || x === 1) {
    return x;
  }
 
  let y = BigInt(x >> 1n);
  while (y > BigInt(x / y)) {
    y = BigInt((BigInt(x) / BigInt(y) + BigInt(y)) >> 1n);
  }
  return y;
}
 
function sqrtC(x) {
  const y = sqrtF(x);
 
  if (x === y * y) {
    return y;
  } else {
    return y + 1n;
  }
}
 
function FermatFactors(n) {
  const ONE = 1n;
  const ZERO = 0n;
  const TWO = 2n;
 
  if (n % TWO === ZERO) {
    return `${n / TWO}, 2`;
  }
 
  const a = sqrtC(n);
 
  if (a * a === n) {
    return `${a}, ${a}`;
  }
 
  let b;
  while (true) {
    const b1 = a * a - n;
    b = sqrtF(b1);
 
    if (b * b === b1) {
      break;
    } else {
      a += 1n;
    }
  }
 
  return `${a - b}, ${a + b}`;
}
 
const N = "105327569";
console.log(FermatFactors(BigInt(N)));

Output:

10223, 10303

Performance Analysis : 

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


My Personal Notes arrow_drop_up
Last Updated : 22 Mar, 2023
Like Article
Save Article
Similar Reads
Related Tutorials