Given a number n, check if it is prime or not. We have introduced and discussed the School method for primality testing in Set 1.
Introduction to Primality Test and School Method
In this post, Fermat’s method is discussed. This method is a probabilistic method and is based on Fermat’s Little Theorem.
Fermat's Little Theorem:
If n is a prime number, then for every a, 1 < a < n-1,
an-1 ≡ 1 (mod n)
OR
an-1 % n = 1
Example: Since 5 is prime, 24 ≡ 1 (mod 5) [or 24%5 = 1],
34 ≡ 1 (mod 5) and 44 ≡ 1 (mod 5)
Since 7 is prime, 26 ≡ 1 (mod 7),
36 ≡ 1 (mod 7), 46 ≡ 1 (mod 7)
56 ≡ 1 (mod 7) and 66 ≡ 1 (mod 7)
Refer this for different proofs.
If a given number is prime, then this method always returns true. If the given number is composite (or non-prime), then it may return true or false, but the probability of producing incorrect results for composite is low and can be reduced by doing more iterations.
Below is algorithm:
// Higher value of k indicates probability of correct
// results for composite inputs become higher. For prime
// inputs, result is always correct
1) Repeat following k times:
a) Pick a randomly in the range [2, n - 2]
b) If gcd(a, n) ≠ 1, then return false
c) If an-1 ≢ 1 (mod n), then return false
2) Return true [probably prime].
Below is the implementation of the above algorithm. The code uses power function from Modular Exponentiation
C++
#include <bits/stdc++.h>
using namespace std;
int power( int a, unsigned int n, int p)
{
int res = 1;
a = a % p;
while (n > 0)
{
if (n & 1)
res = (res*a) % p;
n = n>>1;
a = (a*a) % p;
}
return res;
}
int gcd( int a, int b)
{
if (a < b)
return gcd(b, a);
else if (a%b == 0)
return b;
else return gcd(b, a%b);
}
bool isPrime(unsigned int n, int k)
{
if (n <= 1 || n == 4) return false ;
if (n <= 3) return true ;
while (k>0)
{
int a = 2 + rand ()%(n-4);
if (gcd(n, a) != 1)
return false ;
if (power(a, n-1, n) != 1)
return false ;
k--;
}
return true ;
}
int main()
{
int k = 3;
isPrime(11, k)? cout << " true\n" : cout << " false\n" ;
isPrime(15, k)? cout << " true\n" : cout << " false\n" ;
return 0;
}
|
Java
import java.io.*;
import java.math.*;
class GFG {
static int power( int a, int n, int p)
{
int res = 1 ;
a = a % p;
while (n > 0 )
{
if ((n & 1 ) == 1 )
res = (res * a) % p;
n = n >> 1 ;
a = (a * a) % p;
}
return res;
}
static boolean isPrime( int n, int k)
{
if (n <= 1 || n == 4 ) return false ;
if (n <= 3 ) return true ;
while (k > 0 )
{
int a = 2 + ( int )(Math.random() % (n - 4 ));
if (power(a, n - 1 , n) != 1 )
return false ;
k--;
}
return true ;
}
public static void main(String args[])
{
int k = 3 ;
if (isPrime( 11 , k))
System.out.println( " true" );
else
System.out.println( " false" );
if (isPrime( 15 , k))
System.out.println( " true" );
else
System.out.println( " false" );
}
}
|
Python3
import random
def power(a, n, p):
res = 1
a = a % p
while n > 0 :
if n % 2 :
res = (res * a) % p
n = n - 1
else :
a = (a * * 2 ) % p
n = n / / 2
return res % p
def isPrime(n, k):
if n = = 1 or n = = 4 :
return False
elif n = = 2 or n = = 3 :
return True
else :
for i in range (k):
a = random.randint( 2 , n - 2 )
if power(a, n - 1 , n) ! = 1 :
return False
return True
k = 3
if isPrime( 11 , k):
print ( "true" )
else :
print ( "false" )
if isPrime( 15 , k):
print ( "true" )
else :
print ( "false" )
|
C#
using System;
class GFG {
static int power( int a, int n, int p)
{
int res = 1;
a = a % p;
while (n > 0)
{
if ((n & 1) == 1)
res = (res * a) % p;
n = n >> 1;
a = (a * a) % p;
}
return res;
}
static bool isPrime( int n, int k)
{
if (n <= 1 || n == 4) return false ;
if (n <= 3) return true ;
while (k > 0)
{
Random rand = new Random();
int a = 2 + ( int )(rand.Next() % (n - 4));
if (power(a, n - 1, n) != 1)
return false ;
k--;
}
return true ;
}
static void Main() {
int k = 3;
if (isPrime(11, k))
Console.WriteLine( " true" );
else
Console.WriteLine( " false" );
if (isPrime(15, k))
Console.WriteLine( " true" );
else
Console.WriteLine( " false" );
}
}
|
PHP
<?php
function power( $a , $n , $p )
{
$res = 1;
$a = $a % $p ;
while ( $n > 0)
{
if ( $n & 1)
$res = ( $res * $a ) % $p ;
$n = $n >> 1;
$a = ( $a * $a ) % $p ;
}
return $res ;
}
function isPrime( $n , $k )
{
if ( $n <= 1 || $n == 4)
return false;
if ( $n <= 3)
return true;
while ( $k > 0)
{
$a = 2 + rand() % ( $n - 4);
if (power( $a , $n -1, $n ) != 1)
return false;
$k --;
}
return true;
}
$k = 3;
$res = isPrime(11, $k ) ? " true\n" : " false\n" ;
echo ( $res );
$res = isPrime(15, $k ) ? " true\n" : " false\n" ;
echo ( $res );
?>
|
Javascript
<script>
function power( a, n, p)
{
let res = 1;
a = a % p;
while (n > 0)
{
if ((n & 1) == 1)
res = (res * a) % p;
n = n >> 1;
a = (a * a) % p;
}
return res;
}
function isPrime( n, k)
{
if (n <= 1 || n == 4) return false ;
if (n <= 3) return true ;
while (k > 0)
{
let a = Math.floor(Math.random()* (n-1 - 2) + 2);
if (power(a, n - 1, n) != 1)
return false ;
k--;
}
return true ;
}
let k = 3;
if (isPrime(11, k))
document.write( " true" + "</br>" );
else
document.write( " false" + "</br>" );
if (isPrime(15, k))
document.write( " true" + "</br>" );
else
document.write( " false" + "</br>" );
</script>
|
Output:
true
false
Time complexity: O(k Log n). Note that the power function takes O(Log n) time.
Auxiliary Space: O(min(log a, log b))
Note that the above method may fail even if we increase the number of iterations (higher k). There exist some composite numbers with the property that for every a < n and gcd(a, n) = 1 we have an-1 ≡ 1 (mod n). Such numbers are called Carmichael numbers. Fermat’s primality test is often used if a rapid method is needed for filtering, for example in the key generation phase of the RSA public key cryptographic algorithm.
We will soon be discussing more methods for Primality Testing.
References:
https://en.wikipedia.org/wiki/Fermat_primality_test
https://en.wikipedia.org/wiki/Prime_number
http://www.cse.iitk.ac.in/users/manindra/presentations/FLTBasedTests.pdf
https://en.wikipedia.org/wiki/Primality_test
This article is contributed by Ajay. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above