Cyclic Redundancy Check and Modulo-2 Division
Last Updated :
24 May, 2025
Cyclic Redundancy Check or CRC is a method of detecting accidental changes/errors in the communication channel. CRC uses Generator Polynomial which is available on both sender and receiver side.
An example generator polynomial is of the form like x3 + x + 1. This generator polynomial represents key 1011. Another example is x2 + 1 that represents key 101.
There are two primary variables in CRC:
- n: Number of bits in data to be sent from sender side
- k: Number of bits in the key obtained from generator polynomial.
Encoded Data Generation from Generator Polynomial (Sender Side)
- The binary data is first augmented by adding k-1 zeros in the end of the data.
- Then, modulo - 2 binary division is used to divide binary data by the key and remainder of division is stored.
- At last the the remainder is appended at the end of the data to form the encoded data which is later sent.
Checking Error in Transmission (Receiver Side)
- After receiving the data, to check if the data is error free, perform the modulo-2 division again.
- If the remainder is 0, then there are not errors, otherwise, the data is faulty and contain transmission errors.
Modulo 2 Division
The process of modulo-2 binary division is the same as the familiar division process we use for decimal numbers. Just that instead of subtraction, we use XOR here.
- In each step, a copy of the divisor (or data) is XORed with the k bits of the dividend (or key).
- The result of the XOR operation (remainder) is (k-1) bits, which is used for the next step after 1 extra bit is pulled down to make it k bits long.
- When there are no bits left to pull down, we have a result. The (k-1) bit remainder which is appended at the sender side.
Examples:
Case 1: No error in transmission
Data = 100100, Generator Polynomial (Key) = x3 + x2 + 1 (1101)
Sender Side
Generating RemainderThe remainder is 001. Thus the data sent is 100100001.
Receiver Side
Code word received at the receiver side 100100001
Checking the RemainderThe remainder is 0, hence the data received has no errors.
CRC Implementation - O(n) Time and O(n) Space
Case 2: Error in Transmission
Data = 100100, Generator Polynomial (Key) = x3 + x2 + 1 (1101)
Sender Side
The remainder is 001. Thus the data sent is 100100001.
Receiver Side
Let there be an error and code word received at the receiver side 100000001.

As the remainder is not 0, hence there is some error detected in the receiver side.
Implementation of Cyclic Redundancy Check
The idea is to firstly generate the encoded data by appending the remainder of modulo - 2 division of data and key in the given data. Then, repeat the same process for the data received, and if the decoded data contains any '1', then there is some error in transmission, otherwise the correct data is received.
Follow the below given step-by-step process:
- Start by appending k-1 zeroes to data to form a new string str, where k is the length of key.
- Compute the remainder by calling mod2div with dividend set to str and divisor set to key. In mod2div, first slice dividend to the length of divisor, then repeatedly perform the following:
- If the first character of the current slice (tmp) is '1', call findXor with divisor and tmp; otherwise, call findXor with a string of pick zeroes and tmp.
- Append the next bit of dividend to the result and increment pick.
- The function findXor calculates the XOR of two strings a and b by traversing from index 1 to the end: if corresponding bits are the same, it appends "0" to result, otherwise "1".
- After processing the entire dividend, mod2div returns the final remainder. Append this remainder to data to form the encoded codeword.
- At the receiver side, extract the first n bits of code and perform mod2div with key to obtain curXor. Then, while cur is not equal to code.size, if curXor’s length is not equal to key’s length, append the next bit from code; otherwise, update curXor by performing mod2div on it.
- Finally, if curXor’s length equals key’s length, perform a final mod2div. If curXor contains any '1', the data is incorrect; otherwise, the data is correct.
Below is given the implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Performs bitwise XOR between two binary strings (a and b)
string findXor(string a, string b) {
int n = b.length();
string result = "";
// Compare each bit (skip first bit as per CRC standard)
for (int i = 1; i < n; i++) {
if (a[i] == b[i])
result += "0";
else
result += "1";
}
return result;
}
// Performs Modulo-2 division (CRC division algorithm)
string mod2div(string dividend, string divisor) {
int n = dividend.length();
int pick = divisor.length();
string tmp = dividend.substr(0, pick); // Initial window
while (pick < n) {
if (tmp[0] == '1')
// XOR with divisor and bring down next bit
tmp = findXor(divisor, tmp) + dividend[pick];
else
// XOR with zeros and bring down next bit
tmp = findXor(string(pick, '0'), tmp) + dividend[pick];
pick++;
}
// Final XOR step
if (tmp[0] == '1')
tmp = findXor(divisor, tmp);
else
tmp = findXor(string(pick, '0'), tmp);
return tmp;
}
// Appends CRC remainder to the original data
string encodeData(string data, string key) {
int n = key.length();
string paddedData = data + string(n - 1, '0'); // Append n-1 zeros
string remainder = mod2div(paddedData, key);
return data + remainder; // Return data + CRC
}
// Checks if received data has errors (remainder = 0)
int receiver(string code, string key) {
string remainder = mod2div(code, key);
return (remainder.find('1') == string::npos) ? 1 : 0;
}
int main() {
string data = "100100";
string key = "1101";
cout << "Sender Side" << endl;
cout << "Data: " << data << endl;
cout << "Key: " << key << endl;
string code = encodeData(data, key);
cout << "Encoded Data: " << code << endl << endl;
cout << "Receiver Side" << endl;
if (receiver(code, key))
cout << "Data is correct (No errors detected)" << endl;
else
cout << "Data is incorrect (Error detected)" << endl;
return 0;
}
Java
import java.util.*;
class GfG {
// Returns XOR of 'a' and 'b' (bitwise comparison)
static String findXor(String a, String b) {
int n = b.length();
StringBuilder result = new StringBuilder();
// Compare each bit (skip first bit as per original logic)
for (int i = 1; i < n; i++) {
if (a.charAt(i) == b.charAt(i)) {
result.append('0');
} else {
result.append('1');
}
}
return result.toString();
}
// Performs Modulo-2 division (CRC division)
static String mod2div(String dividend, String divisor) {
int n = dividend.length();
int pick = divisor.length();
String tmp = dividend.substring(0, pick);
while (pick < n) {
if (tmp.charAt(0) == '1') {
// XOR with divisor and bring down next bit
tmp = findXor(divisor, tmp) + dividend.charAt(pick);
} else {
// XOR with zeros and bring down next bit
tmp = findXor(String.format("%0" + pick + "d", 0), tmp)
+ dividend.charAt(pick);
}
pick += 1;
}
// Final XOR step
if (tmp.charAt(0) == '1') {
tmp = findXor(divisor, tmp);
} else {
tmp = findXor(String.format("%0" + pick + "d", 0), tmp);
}
return tmp;
}
// Appends CRC remainder to original data
public static String encodeData(String data, String key) {
int n = key.length();
String str = data + String.join("", Collections.nCopies(n - 1, "0"));
String remainder = mod2div(str, key);
return data + remainder;
}
// Checks if received data has errors
public static int receiver(String code, String key) {
String remainder = mod2div(code, key);
return remainder.contains("1") ? 0 : 1;
}
public static void main(String[] args) {
String data = "100100";
String key = "1101";
System.out.println("Sender Side");
System.out.println("Data: " + data);
System.out.println("Key: " + key);
String code = encodeData(data, key);
System.out.println("Encoded Data: " + code + "\n");
System.out.println("Receiver Side");
if (receiver(code, key) == 1) {
System.out.println("Data is correct (No errors detected)");
} else {
System.out.println("Data is incorrect (Error detected)");
}
}
}
Python
def findXor(a, b):
#Performs bitwise XOR between two binary strings (a and b).
n = len(b)
result = ""
for i in range(1, n): # Skip first bit (CRC standard)
result += '0' if a[i] == b[i] else '1'
return result
def mod2div(dividend, divisor):
# Performs Modulo-2 division (CRC division algorithm).
n = len(dividend)
pick = len(divisor)
tmp = dividend[0:pick] # Initial window
while pick < n:
if tmp[0] == '1':
# XOR with divisor and bring down next bit
tmp = findXor(divisor, tmp) + dividend[pick]
else:
# XOR with zeros and bring down next bit
tmp = findXor('0' * pick, tmp) + dividend[pick]
pick += 1
# Final XOR step
if tmp[0] == '1':
tmp = findXor(divisor, tmp)
else:
tmp = findXor('0' * pick, tmp)
return tmp
def encodeData(data, key):
# Appends CRC remainder to the original data.
n = len(key)
# Append n-1 zeros
padded_data = data + '0' * (n - 1)
remainder = mod2div(padded_data, key)
# Return data + CRC
return data + remainder
def receiver(code, key):
# Checks if received data has errors (remainder = 0).
remainder = mod2div(code, key)
return 1 if '1' not in remainder else 0
if __name__ == "__main__":
data = "100100"
key = "1101"
print("Sender Side")
print("Data:", data)
print("Key:", key)
code = encodeData(data, key)
print("Encoded Data:", code, "\n")
print("Receiver Side")
if receiver(code, key):
print("Data is correct (No errors detected)")
else:
print("Data is incorrect (Error detected)")
C#
using System;
using System.Text;
class GfG {
// Returns XOR of 'a' and 'b' (bitwise comparison)
private static string FindXor(string a, string b){
int n = b.Length;
StringBuilder result = new StringBuilder();
// Compare each bit (skip first bit as per original
// logic)
for (int i = 1; i < n; i++) {
if (a[i] == b[i]) {
result.Append('0');
}
else {
result.Append('1');
}
}
return result.ToString();
}
// Performs Modulo-2 division (CRC division)
static string Mod2Div(string dividend, string divisor){
int n = dividend.Length;
int pick = divisor.Length;
string tmp = dividend.Substring(0, pick);
while (pick < n) {
if (tmp[0] == '1') {
// XOR with divisor and bring down next bit
tmp = FindXor(divisor, tmp)
+ dividend[pick];
}
else {
// XOR with zeros and bring down next bit
tmp = FindXor(new string('0', pick), tmp)
+ dividend[pick];
}
pick += 1;
}
// Final XOR step
if (tmp[0] == '1') {
tmp = FindXor(divisor, tmp);
}
else {
tmp = FindXor(new string('0', pick), tmp);
}
return tmp;
}
// Appends CRC remainder to original data
public static string EncodeData(string data, string key){
int n = key.Length;
string str = data + new string('0', n - 1);
string remainder = Mod2Div(str, key);
return data + remainder;
}
// Checks if received data has errors
public static int Receiver(string code, string key){
string remainder = Mod2Div(code, key);
return remainder.Contains("1") ? 0 : 1;
}
static void Main(){
string data = "100100";
string key = "1101";
Console.WriteLine("Sender Side");
Console.WriteLine("Data: " + data);
Console.WriteLine("Key: " + key);
string code = EncodeData(data, key);
Console.WriteLine("Encoded Data: " + code + "\n");
Console.WriteLine("Receiver Side");
if (Receiver(code, key) == 1) {
Console.WriteLine("Data is correct (No errors detected)");
}
else {
Console.WriteLine( "Data is incorrect (Error detected)");
}
}
}
JavaScript
// Performs bitwise XOR between two binary strings (a and b)
function findXor(a, b){
let n = b.length;
let result = "";
for (let i = 1; i < n; i++) {
// Skip first bit (CRC standard)
result += (a[i] === b[i]) ? "0" : "1";
}
return result;
}
// Performs Modulo-2 division (CRC division algorithm)
function mod2div(dividend, divisor){
let n = dividend.length;
let pick = divisor.length;
let tmp = dividend.substring(0, pick);
while (pick < n) {
if (tmp[0] === "1") {
// XOR with divisor and bring down next bit
tmp = findXor(divisor, tmp) + dividend[pick];
}
else {
// XOR with zeros and bring down next bit
tmp = findXor("0".repeat(pick), tmp)
+ dividend[pick];
}
pick++;
}
// Final XOR step
if (tmp[0] === "1") {
tmp = findXor(divisor, tmp);
}
else {
tmp = findXor("0".repeat(pick), tmp);
}
return tmp;
}
// Appends CRC remainder to the original data
function encodeData(data, key){
const n = key.length;
// Append n-1 zeros
const paddedData = data + "0".repeat(n - 1);
const remainder = mod2div(paddedData, key);
// Return data + CRC
return data + remainder;
}
// Checks if received data has errors (remainder = 0)
function receiver(code, key){
const remainder = mod2div(code, key);
return remainder.includes("1") ? 0 : 1;
}
// Driver Code
const data = "100100";
const key = "1101";
console.log("Sender Side");
console.log("Data:", data);
console.log("Key:", key);
const code = encodeData(data, key);
console.log("Encoded Data:", code, "\n");
console.log("Receiver Side");
if (receiver(code, key)) {
console.log("Data is correct (No errors detected)");
}
else {
console.log("Data is incorrect (Error detected)");
}
OutputSender Side
Data: 100100
Key: 1101
Encoded Data: 100100001
Receiver Side
Data is correct (No errors detected)
CRC Implementation Using Bit Manipulation - O(n) Time and O(n) Space
The idea is to manipulate the given binary strings by converting them to decimal numbers, and process them. After processing the numbers, convert them back to binary strings.
Follow the below given step-by-step approach:
- Determine n as key.length() and convert key to decimal using toDec(key) to get gen, and convert data to decimal using toDec(data) to get code.
- Append n-1 zeroes to data by left-shifting code by (n - 1) and store the result in dividend.
- Compute shft as ceill(log2l(dividend + 1)) - n, which represents the number of least significant bits not involved in the XOR operation.
- While (dividend >= gen) or (shft >= 0):
- Calculate rem as (dividend >> shft) XOR gen.
- Update dividend by combining the unchanged lower shft bits (dividend & ((1 << shft) - 1)) with the new bits (rem << shft) resulting from the XOR operation.
- Recalculate shft as ceil(log2l(dividend + 1)) - n.
- After the loop, compute codeword as the bitwise OR of (code << (n - 1)) and dividend.
- Finally, output the remainder (obtained by converting dividend to binary using toBin(dividend)) and the codeword (obtained by converting codeword to binary using toBin(codeword)).
C++
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
#define int long long int
// Function to convert integer to binary string
string toBin(int num) {
// Handle case when number is 0
if (num == 0) return "0";
string bin = "";
while (num) {
// Append '1' or '0' based on least significant bit
bin += (num & 1) ? '1' : '0';
// Shift right to process next bit
num = num >> 1;
}
// Reverse string since bits were added in reverse order
reverse(bin.begin(), bin.end());
return bin;
}
// Function to convert binary string to decimal integer
int toDec(string bin) {
int n = bin.size();
// Handle empty string
if (n == 0) return 0;
int num = 0;
for (int i = 0; i < n; i++) {
if (bin[i] == '1') {
// Compute power of 2 for each '1' in binary string
num += 1 << (n - i - 1);
}
}
return num;
}
// Function to compute CRC and print remainder and codeword
void CRC(string data, string key) {
int n = key.length();
if (n == 0) {
cout << "Error: Key cannot be empty" << endl;
return;
}
// Convert binary strings to decimal integers
// Generator polynomial (key)
int gen = toDec(key);
// Original data
int code = toDec(data);
// Append (n - 1) zeros to the data to make space for CRC bits
int dividend = code << (n - 1);
// Calculate the position to start XOR (most significant bit position)
int shft;
while ((shft = (int)log2(dividend) - n + 1) >= 0) {
// Extract top 'n' bits of dividend, XOR with generator polynomial
int rem = (dividend >> shft) ^ gen;
// Replace top bits in dividend with XOR result (remainder)
dividend = (dividend & ((1 << shft) - 1)) | (rem << shft);
}
// Final codeword is the original data with the remainder appended
int codeword = (code << (n - 1)) | dividend;
// Print results
cout << "Remainder: " << toBin(dividend) << endl;
cout << "Codeword : " << toBin(codeword) << endl;
}
signed main() {
string data = "100100";
string key = "1101";
CRC(data, key);
return 0;
}
Java
import java.util.Collections;
class GfG {
// Function to convert integer to binary string
public static String toBin(int num) {
// Handle case when number is 0
if (num == 0) return "0";
StringBuilder bin = new StringBuilder();
while (num != 0) {
// Append '1' or '0' based on least significant bit
bin.append((num & 1) == 1 ? '1' : '0');
// Shift right to process next bit
num = num >> 1;
}
// Reverse string since bits were added in reverse order
return bin.reverse().toString();
}
// Function to convert binary string to decimal integer
public static int toDec(String bin) {
int n = bin.length();
// Handle empty string
if (n == 0) return 0;
int num = 0;
for (int i = 0; i < n; i++) {
if (bin.charAt(i) == '1') {
// Compute power of 2 for each '1' in binary string
num += 1 << (n - i - 1);
}
}
return num;
}
// Function to compute CRC and print remainder and codeword
public static void CRC(String data, String key) {
int n = key.length();
if (n == 0) {
System.out.println("Error: Key cannot be empty");
return;
}
// Convert binary strings to decimal integers
// Generator polynomial (key)
int gen = toDec(key);
// Original data
int code = toDec(data);
// Append (n - 1) zeros to the data to make space for CRC bits
int dividend = code << (n - 1);
// Calculate the position to start XOR (most significant bit position)
int shft;
while ((shft = (int)(Math.log(dividend) / Math.log(2)) - n + 1) >= 0) {
// Extract top 'n' bits of dividend, XOR with generator polynomial
int rem = (dividend >> shft) ^ gen;
// Replace top bits in dividend with XOR result (remainder)
dividend = (dividend & ((1 << shft) - 1)) | (rem << shft);
}
// Final codeword is the original data with the remainder appended
int codeword = (code << (n - 1)) | dividend;
// Print results
System.out.println("Remainder: " + toBin(dividend));
System.out.println("Codeword : " + toBin(codeword));
}
public static void main(String[] args) {
String data = "100100";
String key = "1101";
CRC(data, key);
}
}
Python
def toBin(num):
"""Convert integer to binary string"""
if num == 0:
return "0"
bin_str = ""
while num:
# Append '1' or '0' based on least significant bit
bin_str += '1' if num & 1 else '0'
# Shift right to process next bit
num = num >> 1
# Reverse string since bits were added in reverse order
return bin_str[::-1]
def toDec(bin_str):
"""Convert binary string to decimal integer"""
n = len(bin_str)
if n == 0:
return 0
num = 0
for i in range(n):
if bin_str[i] == '1':
# Compute power of 2 for each '1' in binary string
num += 1 << (n - i - 1)
return num
def CRC(data, key):
"""Compute CRC and print remainder and codeword"""
n = len(key)
if n == 0:
print("Error: Key cannot be empty")
return
# Convert binary strings to decimal integers
gen = toDec(key) # Generator polynomial (key)
code = toDec(data) # Original data
# Append (n - 1) zeros to the data to make space for CRC bits
dividend = code << (n - 1)
# Calculate the position to start XOR (most significant bit position)
shft = 0
while True:
current_shft = dividend.bit_length() - n
if current_shft < 0:
break
# Extract top 'n' bits of dividend, XOR with generator polynomial
rem = (dividend >> current_shft) ^ gen
# Replace top bits in dividend with XOR result (remainder)
dividend = (dividend & ((1 << current_shft) - 1)) | (rem << current_shft)
# Final codeword is the original data with the remainder appended
codeword = (code << (n - 1)) | dividend
# Print results
print(f"Remainder: {toBin(dividend)}")
print(f"Codeword : {toBin(codeword)}")
if __name__ == "__main__":
data = "100100"
key = "1101"
CRC(data, key)
C#
using System;
using System.Text;
class GfG{
// Function to convert integer to binary string
static string toBin(int num){
// Handle case when number is 0
if (num == 0) return "0";
StringBuilder bin = new StringBuilder();
while (num != 0){
// Append '1' or '0' based on least significant bit
bin.Append((num & 1) == 1 ? '1' : '0');
// Shift right to process next bit
num = num >> 1;
}
// Reverse string since bits were added in reverse order
char[] charArray = bin.ToString().ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
// Function to convert binary string to decimal integer
static int toDec(string bin){
int n = bin.Length;
// Handle empty string
if (n == 0) return 0;
int num = 0;
for (int i = 0; i < n; i++){
if (bin[i] == '1'){
// Compute power of 2 for each '1' in binary string
num += 1 << (n - i - 1);
}
}
return num;
}
// Function to compute CRC and print remainder and codeword
static void CRC(string data, string key){
int n = key.Length;
if (n == 0){
Console.WriteLine("Error: Key cannot be empty");
return;
}
// Convert binary strings to decimal integers
// Generator polynomial (key)
int gen = toDec(key);
// Original data
int code = toDec(data);
// Append (n - 1) zeros to the data to make space for CRC bits
int dividend = code << (n - 1);
// Calculate the position to start XOR (most significant bit position)
int shft;
while ((shft = (int)(Math.Log(dividend, 2)) - n + 1) >= 0){
// Extract top 'n' bits of dividend, XOR with generator polynomial
int rem = (dividend >> shft) ^ gen;
// Replace top bits in dividend with XOR result (remainder)
dividend = (dividend & ((1 << shft) - 1)) | (rem << shft);
}
// Final codeword is the original data with the remainder appended
int codeword = (code << (n - 1)) | dividend;
// Print results
Console.WriteLine("Remainder: " + toBin(dividend));
Console.WriteLine("Codeword : " + toBin(codeword));
}
static void Main(){
string data = "100100";
string key = "1101";
CRC(data, key);
}
}
JavaScript
function toBin(num) {
// Convert integer to binary string
if (num === 0) return "0";
let bin = "";
while (num > 0) {
// Append '1' or '0' based on least significant bit
bin = (num & 1 ? "1" : "0") + bin;
// Shift right to process next bit
num = num >>> 1;
}
return bin || "0";
}
function toDec(bin) {
// Convert binary string to decimal integer
const n = bin.length;
if (n === 0) return 0;
let num = 0;
for (let i = 0; i < n; i++) {
if (bin[i] === '1') {
// Compute power of 2 for each '1' in binary string
num += 1 << (n - i - 1);
}
}
return num;
}
function CRC(data, key) {
// Compute CRC and print remainder and codeword
const n = key.length;
if (n === 0) {
console.log("Error: Key cannot be empty");
return;
}
// Convert binary strings to decimal integers
// Generator polynomial (key)
const gen = toDec(key);
// Original data
const code = toDec(data);
// Append (n - 1) zeros to the data to make space for CRC bits
let dividend = code << (n - 1);
// Calculate the position to start XOR (most significant bit position)
let shft;
while ((shft = Math.floor(Math.log2(dividend)) - n + 1) >= 0) {
// Extract top 'n' bits of dividend, XOR with generator polynomial
const rem = (dividend >> shft) ^ gen;
// Replace top bits in dividend with XOR result (remainder)
dividend = (dividend & ((1 << shft) - 1)) | (rem << shft);
}
// Final codeword is the original data with the remainder appended
const codeword = (code << (n - 1)) | dividend;
// Print results
console.log(`Remainder: ${toBin(dividend)}`);
console.log(`Codeword : ${toBin(codeword)}`);
}
// Driver Code
const data = "100100";
const key = "1101";
CRC(data, key);
OutputRemainder: 1
Codeword : 100100001
Similar Reads
Number Theory for DSA & Competitive Programming What is Number Theory?Number theory is a branch of pure mathematics that deals with the properties and relationships of numbers, particularly integers. It explores the fundamental nature of numbers and their mathematical structures. Number theory has been studied for centuries and has deep connectio
3 min read
Number Theory (Interesting Facts and Algorithms) Questions based on various concepts of number theory and different types of number are quite frequently asked in programming contests. In this article, we discuss some famous facts and algorithms:Interesting Facts of Number Theory :1. All 4 digit palindromic numbers are divisible by 11.2. If we repe
5 min read
How to prepare for ACM - ICPC? ACM ICPC(Association for Computing Machinery - International Collegiate Programming Contest) is a worldwide annual multi-tiered programming contest being organized for over thirteen years. The contest is sponsored by IBM. This article focuses on what all topics that are important for competitive pro
7 min read
Basics of Number Theory
Program to Find GCD or HCF of Two NumbersGiven two positive integers a and b, the task is to find the GCD of the two numbers.Note: The GCD (Greatest Common Divisor) or HCF (Highest Common Factor) of two numbers is the largest number that divides both of them. Examples:Input: a = 20, b = 28Output: 4Explanation: The factors of 20 are 1, 2, 4
12 min read
Program to find LCM of two numbersLCM of two numbers is the smallest number which can be divided by both numbers. Input : a = 12, b = 18Output : 3636 is the smallest number divisible by both 12 and 18Input : a = 5, b = 11Output : 5555 is the smallest number divisible by both 5 and 11[Naive Approach] Using Conditional Loop This appro
8 min read
Factorial of a NumberGiven the number n (n >=0), find its factorial. Factorial of n is defined as 1 x 2 x ... x n. For n = 0, factorial is 1. We are going to discuss iterative and recursive programs in this post.Examples:Input: n = 5Output: 120Explanation: 5! = 5 * 4 * 3 * 2 * 1 = 120Input: n = 4Output: 24Explanation
7 min read
Print all prime factors of a given numberGiven a number n, the task is to find all prime factors of n.Examples:Input: n = 24Output: 2 2 2 3Explanation: The prime factorization of 24 is 23Ã3.Input: n = 13195Output: 5 7 13 29Explanation: The prime factorization of 13195 is 5Ã7Ã13Ã29.Approach:Every composite number has at least one prime fact
6 min read
Binomial CoefficientGiven an integer values n and k, the task is to find the value of Binomial Coefficient C(n, k).A binomial coefficient C(n, k) can be defined as the coefficient of x^k in the expansion of (1 + x)^n.A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that k objects can be
15+ min read
Program for nth Catalan NumberCatalan numbers are defined as a mathematical sequence that consists of positive integers, which can be used to find the number of possibilities of various combinations. The nth term in the sequence denoted Cn, is found in the following formula: \frac{(2n)!}{((n + 1)! n!)} The first few Catalan numb
13 min read
Euclid's lemmaWe are given two numbers x and y. We know that a number p divides their product. Can we say for sure that p also divides one of them? The answer is no. For example, consider x = 15, y = 6 and p = 9. p divides the product 15*6, but doesn't divide any of them. What if p is prime? Euclid's lemma states
1 min read
Euclidean algorithms (Basic and Extended)The Euclidean algorithm is a way to find the greatest common divisor of two positive integers. GCD of two numbers is the largest number that divides both of them. A simple way to find GCD is to factorize both numbers and multiply common prime factors.Examples:input: a = 12, b = 20Output: 4Explanatio
9 min read
Modular Arithmetic
Modular ArithmeticModular arithmetic is a system of arithmetic for numbers where numbers "wrap around" after reaching a certain value, called the modulus. It mainly uses remainders to get the value after wrap around. It is often referred to as "clock arithmetic. As you can see, the time values wrap after reaching 12
10 min read
Modular AdditionModular addition is a basic math concept used in computers and number systems. It is commonly used in areas like cryptography (data security), coding, and digital signal processing. In modular addition, you add two numbers normally, but if the result reaches a certain fixed number (called the modulu
4 min read
Modular MultiplicationModular arithmetic, or clock arithmetic, is a system of arithmetic for integers, where numbers "wrap around" upon reaching a certain value This mathematical concept is widely used in various fields such as computer science, cryptography, number theory, and even everyday situations like clock time ca
6 min read
Modular DivisionGiven three positive integers a, b, and M, the objective is to find (a/b) % M i.e., find the value of (a à b-1 ) % M, where b-1 is the modular inverse of b modulo M.Examples: Input: a = 10, b = 2, M = 13Output: 5Explanation: The modular inverse of 2 modulo 13 is 7, so (10 / 2) % 13 = (10 à 7) % 13 =
13 min read
Euler's Totient FunctionGiven an integer n, find the value of Euler's Totient Function, denoted as Φ(n). The function Φ(n) represents the count of positive integers less than or equal to n that are relatively prime to n. Euler's Totient function Φ(n) for an input n is the count of numbers in {1, 2, 3, ..., n-1} that are re
10 min read
Euler's Totient function for all numbers smaller than or equal to nEuler's Totient function ?(n) for an input n is the count of numbers in {1, 2, 3, ..., n} that are relatively prime to n, i.e., the numbers whose GCD (Greatest Common Divisor) with n is 1. For example, ?(4) = 2, ?(3) = 2 and ?(5) = 4. There are 2 numbers smaller or equal to 4 that are relatively pri
13 min read
Modular Exponentiation (Power in Modular Arithmetic)Given three integers x, n, and M, compute (x^n) % M (remainder when x raised to the power n is divided by M).Examples : Input: x = 3, n = 2, M = 4Output: 1Explanation: 32 % 4 = 9 % 4 = 1.Input: x = 2, n = 6, M = 10Output: 4Explanation: 26 % 10 = 64 % 10 = 4.Table of Content[Naive Approach] Repeated
6 min read
Program to find remainder without using modulo or % operatorGiven two numbers 'num' and 'divisor', find remainder when 'num' is divided by 'divisor'. The use of modulo or % operator is not allowed.Examples : Input: num = 100, divisor = 7 Output: 2 Input: num = 30, divisor = 9 Output: 3 Method 1 : C++ // C++ program to find remainder without using // modulo o
9 min read
Modular multiplicative inverseGiven two integers A and M, find the modular multiplicative inverse of A under modulo M.The modular multiplicative inverse is an integer X such that:A X â¡ 1 (mod M) Note: The value of X should be in the range {1, 2, ... M-1}, i.e., in the range of integer modulo M. ( Note that X cannot be 0 as A*0 m
15+ min read
Multiplicative orderIn number theory, given an integer A and a positive integer N with gcd( A , N) = 1, the multiplicative order of a modulo N is the smallest positive integer k with A^k( mod N ) = 1. ( 0 < K < N ) Examples : Input : A = 4 , N = 7 Output : 3 explanation : GCD(4, 7) = 1 A^k( mod N ) = 1 ( smallest
7 min read
Compute nCr%p using Lucas TheoremGiven three numbers n, r and p, compute the value of nCr mod p. Examples: Input: n = 10, r = 2, p = 13 Output: 6 Explanation: 10C2 is 45 and 45 % 13 is 6. Input: n = 1000, r = 900, p = 13 Output: 8 We strongly recommend referring below post as a prerequisite of this.Compute nCr % p | Set 1 (Introduc
12 min read
Compute nCr%p using Fermat Little TheoremGiven three numbers n, r and p, compute the value of nCr mod p. Here p is a prime number greater than n. Here nCr is Binomial Coefficient.Example: Input: n = 10, r = 2, p = 13 Output: 6 Explanation: 10C2 is 45 and 45 % 13 is 6. Input: n = 6, r = 2, p = 13 Output: 2Recommended PracticenCrTry It! We h
15+ min read
Introduction to Chinese Remainder TheoremWe are given two arrays num[0..k-1] and rem[0..k-1]. In num[0..k-1], every pair is coprime (gcd for every pair is 1). We need to find minimum positive number x such that: x % num[0] = rem[0], x % num[1] = rem[1], .......................x % num[k-1] = rem[k-1] Basically, we are given k numbers which
7 min read
Implementation of Chinese Remainder theorem (Inverse Modulo based implementation)We are given two arrays num[0..k-1] and rem[0..k-1]. In num[0..k-1], every pair is coprime (gcd for every pair is 1). We need to find minimum positive number x such that: x % num[0] = rem[0], x % num[1] = rem[1], ....................... x % num[k-1] = rem[k-1] Example: Input: num[] = {3, 4, 5}, rem[
11 min read
Find Square Root under Modulo p | Set 1 (When p is in form of 4*i + 3)Given a number 'n' and a prime 'p', find square root of n under modulo p if it exists. It may be given that p is in the form for 4*i + 3 (OR p % 4 = 3) where i is an integer. Examples of such primes are 7, 11, 19, 23, 31, ... etc,Examples: Input: n = 2, p = 7Output: 3 or 4Explanation: 3 and 4 both a
14 min read
Find Square Root under Modulo p | Set 2 (Shanks Tonelli algorithm)Given a number ânâ and a prime âpâ, find square root of n under modulo p if it exists. Examples: Input: n = 2, p = 113 Output: 62 62^2 = 3844 and 3844 % 113 = 2 Input: n = 2, p = 7 Output: 3 or 4 3 and 4 both are square roots of 2 under modulo 7 because (3*3) % 7 = 2 and (4*4) % 7 = 2 Input: n = 2,
15+ min read
Modular DivisionGiven three positive integers a, b, and M, the objective is to find (a/b) % M i.e., find the value of (a à b-1 ) % M, where b-1 is the modular inverse of b modulo M.Examples: Input: a = 10, b = 2, M = 13Output: 5Explanation: The modular inverse of 2 modulo 13 is 7, so (10 / 2) % 13 = (10 à 7) % 13 =
13 min read
Cyclic Redundancy Check and Modulo-2 DivisionCyclic Redundancy Check or CRC is a method of detecting accidental changes/errors in the communication channel. CRC uses Generator Polynomial which is available on both sender and receiver side. An example generator polynomial is of the form like x3 + x + 1. This generator polynomial represents key
15+ min read
Primitive root of a prime number n modulo nGiven a prime number n, the task is to find its primitive root under modulo n. The primitive root of a prime number n is an integer r between[1, n-1] such that the values of r^x(mod n) where x is in the range[0, n-2] are different. Return -1 if n is a non-prime number. Examples: Input : 7 Output : S
15 min read
Euler's criterion (Check if square root under modulo p exists)Given a number 'n' and a prime p, find if square root of n under modulo p exists or not. A number x is square root of n under modulo p if (x*x)%p = n%p. Examples : Input: n = 2, p = 5 Output: false There doesn't exist a number x such that (x*x)%5 is 2 Input: n = 2, p = 7 Output: true There exists a
11 min read
Using Chinese Remainder Theorem to Combine Modular equationsGiven N modular equations: A ? x1mod(m1) . . A ? xnmod(mn) Find x in the equation A ? xmod(m1*m2*m3..*mn) where mi is prime, or a power of a prime, and i takes values from 1 to n. The input is given as two arrays, the first being an array containing values of each xi, and the second array containing
12 min read
Multiply large integers under large moduloGiven an integer a, b, m. Find (a * b ) mod m, where a, b may be large and their direct multiplication may cause overflow. However, they are smaller than half of the maximum allowed long long int value. Examples: Input: a = 426, b = 964, m = 235Output: 119Explanation: (426 * 964) % 235 = 410664 % 23
7 min read
Compute n! under modulo pGiven a large number n and a prime p, how to efficiently compute n! % p?Examples : Input: n = 5, p = 13 Output: 3 5! = 120 and 120 % 13 = 3 Input: n = 6, p = 11 Output: 5 6! = 720 and 720 % 11 = 5 A Naive Solution is to first compute n!, then compute n! % p. This solution works fine when the value o
15+ min read
Wilson's TheoremWilson's Theorem is a fundamental result in number theory that provides a necessary and sufficient condition for determining whether a given number is prime. It states that a natural number p > 1 is a prime number if and only if:(p - 1)! â¡ â1 (mod p)This means that the factorial of p - 1 (the pro
2 min read
Number Theory
Introduction to Primality Test and School MethodGiven a positive integer, check if the number is prime or not. A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself. Examples of the first few prime numbers are {2, 3, 5, ...}Examples : Input: n = 11Output: trueInput: n = 15Output: falseInput: n = 1Output:
10 min read
Fermat Method of Primality TestGiven 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 MethodIn this post, Fermat's method is discussed. This method is a probabilistic method and is based on Fermat's Little Theorem.
10 min read
Primality Test | Set 3 (MillerâRabin)Given a number n, check if it is prime or not. We have introduced and discussed School and Fermat methods for primality testing.Primality Test | Set 1 (Introduction and School Method) Primality Test | Set 2 (Fermat Method)In this post, the Miller-Rabin method is discussed. This method is a probabili
15+ min read
Solovay-Strassen method of Primality TestWe have already been introduced to primality testing in the previous articles in this series. Introduction to Primality Test and School MethodFermat Method of Primality TestPrimality Test | Set 3 (MillerâRabin)The SolovayâStrassen test is a probabilistic algorithm used to check if a number is prime
13 min read
Legendre's formula - Largest power of a prime p in n!Given an integer n and a prime number p, the task is to find the largest x such that px (p raised to power x) divides n!.Examples: Input: n = 7, p = 3Output: x = 2Explanation: 32 divides 7! and 2 is the largest such power of 3.Input: n = 10, p = 3Output: x = 4Explanation: 34 divides 10! and 4 is the
6 min read
Carmichael NumbersA number n is said to be a Carmichael number if it satisfies the following modular arithmetic condition: power(b, n-1) MOD n = 1, for all b ranging from 1 to n such that b and n are relatively prime, i.e, gcd(b, n) = 1 Given a positive integer n, find if it is a Carmichael number. These numbers have
8 min read
Number Theory | Generators of finite cyclic group under additionGiven a number n, find all generators of cyclic additive group under modulo n. Generator of a set {0, 1, ... n-1} is an element x such that x is smaller than n, and using x (and addition operation), we can generate all elements of the set.Examples: Input : 10 Output : 1 3 7 9 The set to be generated
5 min read
Sum of divisors of factorial of a numberGiven a number n, we need to calculate the sum of divisors of factorial of the number. Examples: Input : 4 Output : 60 Factorial of 4 is 24. Divisors of 24 are 1 2 3 4 6 8 12 24, sum of these is 60. Input : 6 Output : 2418 A Simple Solution is to first compute the factorial of the given number, then
14 min read
GFact | 2x + 1(where x > 0) is prime if and only if x is a power of 2A number of the form 2x + 1 (where x > 0) is prime if and only if x is a power of 2, i.e., x = 2n. So overall number becomes 22n + 1. Such numbers are called Fermat Number (Numbers of form 22n + 1). The first few Fermat numbers are 3, 5, 17, 257, 65537, 4294967297, .... An important thing to note
1 min read
Sieve of EratosthenesGiven a number n, print all primes smaller than or equal to n. It is also given that n is a small number. Examples:Input: n = 10Output: 2 3 5 7Explanation: The prime numbers up to 10 obtained by Sieve of Eratosthenes are 2 3 5 7 .Input: n = 20Output: 2 3 5 7 11 13 17 19Explanation: The prime numbers
6 min read
Program for Goldbachâs Conjecture (Two Primes with given Sum)Goldbach's conjecture is one of the oldest and best-known unsolved problems in the number theory of mathematics. Every even integer greater than 2 can be expressed as the sum of two primes. Examples: Input : n = 44 Output : 3 + 41 (both are primes) Input : n = 56 Output : 3 + 53 (both are primes) Re
12 min read
Pollard's Rho Algorithm for Prime FactorizationGiven a positive integer n, and that it is composite, find a divisor of it.Example:Input: n = 12;Output: 2 [OR 3 OR 4]Input: n = 187;Output: 11 [OR 17]Brute approach: Test all integers less than n until a divisor is found. Improvisation: Test all integers less than ?nA large enough number will still
14 min read
Game Theory
Practice Problems
Rabin-Karp Algorithm for Pattern SearchingGiven two strings text and pattern string, your task is to find all starting positions where the pattern appears as a substring within the text. The strings will only contain lowercase English alphabets.While reporting the results, use 1-based indexing (i.e., the first character of the text is at po
12 min read
Measure one litre using two vessels and infinite water supplyThere are two vessels of capacities 'a' and 'b' respectively. We have infinite water supply. Give an efficient algorithm to make exactly 1 litre of water in one of the vessels. You can throw all the water from any vessel any point of time. Assume that 'a' and 'b' are Coprimes.Following are the steps
15 min read
Program to find last digit of n'th Fibonacci NumberGiven a number 'n', write a function that prints the last digit of n'th ('n' can also be a large number) Fibonacci number. Examples : Input : n = 0 Output : 0 Input: n = 2 Output : 1 Input : n = 7 Output : 3 Recommended PracticeThe Nth FibonnaciTry It! Method 1 : (Naive Method) Simple approach is to
13 min read
GCD of two numbers when one of them can be very largeGiven two numbers 'a' and 'b' such that (0 <= a <= 10^12 and b <= b < 10^250). Find the GCD of two given numbers.Examples : Input: a = 978 b = 89798763754892653453379597352537489494736 Output: 6 Input: a = 1221 b = 1234567891011121314151617181920212223242526272829 Output: 3 Solution : In
9 min read
Find Last Digit of a^b for Large NumbersYou are given two integer numbers, the base a (number of digits d, such that 1 <= d <= 1000) and the index b (0 <= b <= 922*10^15). You have to find the last digit of a^b.Examples: Input : 3 10Output : 9Input : 6 2Output : 6Input : 150 53Output : 0 After taking few examples, we can notic
9 min read
Remainder with 7 for large numbersGiven a large number as a string, find the remainder of number when divided by 7. Examples : Input : num = 1234 Output : 2 Input : num = 1232 Output : 0 Input : num = 12345 Output : 4Recommended PracticeRemainder with 7Try It! Simple Approach is to convert a string into number and perform the mod op
8 min read
Find (a^b)%m where 'a' is very largeGiven three numbers a, b and m where 1<=b,m<=10^6 and 'a' may be very large and contains upto 10^6 digits. The task is to find (a^b)%m. Examples: Input : a = 3, b = 2, m = 4 Output : 1 Explanation : (3^2)%4 = 9%4 = 1 Input : a = 987584345091051645734583954832576, b = 3, m = 11 Output: 10Recomm
15+ min read
Find sum of modulo K of first N natural numberGiven two integer N ans K, the task is to find sum of modulo K of first N natural numbers i.e 1%K + 2%K + ..... + N%K. Examples : Input : N = 10 and K = 2. Output : 5 Sum = 1%2 + 2%2 + 3%2 + 4%2 + 5%2 + 6%2 + 7%2 + 8%2 + 9%2 + 10%2 = 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 = 5.Recommended PracticeReve
9 min read
Count sub-arrays whose product is divisible by kGiven an integer K and an array arr[], the task is to count all the sub-arrays whose product is divisible by K.Examples: Input: arr[] = {6, 2, 8}, K = 4 Output: 4 Required sub-arrays are {6, 2}, {6, 2, 8}, {2, 8}and {8}.Input: arr[] = {9, 1, 14}, K = 6 Output: 1 Naive approach: Run nested loops and
15+ min read
Partition a number into two divisible partsGiven a number (as string) and two integers a and b, divide the string in two non-empty parts such that the first part is divisible by a and the second part is divisible by b. If the string can not be divided into two non-empty parts, output "NO", else print "YES" with the two parts. Examples: Input
15+ min read
Find power of power under mod of a primeGiven four numbers A, B, C and M, where M is prime number. Our task is to compute A raised to power (B raised to power C) modulo M. Example: Input : A = 2, B = 4, C = 3, M = 23Output : 643 = 64 so,2^64(mod 23) = 6 A Naive Approach is to calculate res = BC and then calculate Ares % M by modular expon
7 min read
Rearrange an array in maximum minimum form in O(1) extra spaceGiven a sorted array of positive integers, rearrange the array alternately i.e first element should be the maximum value, second minimum value, third-second max, fourth-second min and so on. Examples:Input: arr[] = {1, 2, 3, 4, 5, 6, 7} Output: arr[] = {7, 1, 6, 2, 5, 3, 4}Explanation: First 7 is th
8 min read
Subset with no pair sum divisible by KGiven an array of integer numbers, we need to find maximum size of a subset such that sum of each pair of this subset is not divisible by K. Examples : Input : arr[] = [3, 7, 2, 9, 1] K = 3 Output : 3 Maximum size subset whose each pair sum is not divisible by K is [3, 7, 1] because, 3+7 = 10, 3+1 =
7 min read
Number of substrings divisible by 6 in a string of integersGiven a string consisting of integers 0 to 9. The task is to count the number of substrings which when convert into integer are divisible by 6. Substring does not contain leading zeroes. Examples: Input : s = "606". Output : 5 Substrings "6", "0", "6", "60", "606" are divisible by 6. Input : s = "48
9 min read
Miscellaneous Practice Problems