Open In App

Fermat’s Factorization method for large numbers

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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: 

C++




#include <iostream>
#include <string>
#include <cmath>
#include <stdexcept>
 
using namespace std;
 
// Function to find the Floor
// of square root of a number
long long sqrtF(long long x)
{
    // if x is less than 0
    if (x < 0)
    {
        throw invalid_argument("Negative argument.");
    }
 
    // if x==0 or x==1
    if (x == 0 || x == 1)
    {
        return x;
    }
 
    long long 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
long long sqrtC(long long x)
{
    long long y = sqrtF(x);
 
    if (x == y * y)
    {
        return y;
    }
    else
    {
        return y + 1;
    }
}
 
// Fermat factorisation
string FermatFactors(long long n)
{
    // if n%2 ==0 then return the factors
    if (n % 2 == 0)
    {
        return to_string(n / 2) + ", 2";
    }
 
    // find the square root
    long long a = sqrtC(n);
 
    // if the number is a perfect square
    if (a * a == n)
    {
        return to_string(a) + ", " + to_string(a);
    }
 
    // else perform factorisation
    long long b;
    while (true)
    {
        long long b1 = a * a - n;
        b = sqrtF(b1);
 
        if (b * b == b1)
        {
            break;
        }
        else
        {
            a += 1;
        }
    }
 
    return to_string(a - b) + ", " + to_string(a + b);
}
 
// Driver code
int main()
{
    string N = "105327569";
 
    cout << FermatFactors(stoll(N)) << endl;
 
    return 0;
}
//This code is contributed by Aman


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


C#




using System;
 
public class FermatFactorization
{
    // Function to find the Floor
    // of square root of a number
    public static long SqrtF(long x)
    {
        // if x is less than 0
        if (x < 0)
        {
            throw new ArgumentException("Negative argument.");
        }
 
        // if x==0 or x==1
        if (x == 0 || x == 1)
        {
            return x;
        }
 
        long 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
    public static long SqrtC(long x)
    {
        long y = SqrtF(x);
 
        if (x == y * y)
        {
            return y;
        }
        else
        {
            return y + 1;
        }
    }
 
    // Fermat factorisation
    public static string FermatFactors(long n)
    {
        // if n%2 ==0 then return the factors
        if (n % 2 == 0)
        {
            return (n / 2) + ", 2";
        }
 
        // find the square root
        long a = SqrtC(n);
 
        // if the number is a perfect square
        if (a * a == n)
        {
            return a + ", " + a;
        }
 
        // else perform factorisation
        long b;
        while (true)
        {
            long b1 = a * a - n;
            b = SqrtF(b1);
 
            if (b * b == b1)
            {
                break;
            }
            else
            {
                a += 1;
            }
        }
 
        return (a - b) + ", " + (a + b);
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        string N = "105327569";
 
        Console.WriteLine(FermatFactors(long.Parse(N)));
    }
}
// This code is contributed by Aman


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)



Last Updated : 24 Feb, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads