CRC Program in Java
The acronym CRC stands for Cyclic Redundancy Check. It is invented by W. Wesley Peterson in 1961. It is an error detection technique that detects errors in digital networks (also known as communication channels or digital data) and storage devices. It is used to track down unintentional modifications in digital data. This section will look at how to use a Java program to calculate and perform CRC. Let's take a closer look at CRC.
An error detection system assigns a unique number to each data block. The number is included primarily to identify changes that occur during transmission or storage. During data transmission, it is computed twice, once at the transmitter and again at the receiver. It compares data bit by bit with the original values delivered. If a data transmission error (corrupted bit) occurs, the CRC value does not match the value that was originally transferred. The graphic below helps us understand the CRC mechanism.
Fig:

A single corrupted bit in the data, for example, causes a one-bit change in the calculated CRC, but many corrupted bits may cancel each other out. A burst error happens when a large number of bits are corrupted or changed at the same time.
Other error detection algorithms exist, such as Vertical Redundancy Check (VRC) and Longitudinal Redundancy Check (LRC). However, CRC is more powerful. Because CRC is calculated using binary division, the algorithm is more difficult. The divisor is calculated using polynomials. CRC is hence also known as a polynomial code checksum.
Steps for error detection in CRC:
- In the first phase, N 0's are appended to the data unit. N is always less than the number of bits in the data unit (also known as division, which equals N+1).
- The newly extended data is then split by a divisor using binary division, and the resultant reminder is known as the CRC remainder.
- The remaining bits are then utilised to replace all of the 0's that had previously been added to the data unit. Following that, we handed the freshly created data unit to the receiver.
- The receiver receives the data unit together with the CRC residual. The receiver then divides the data unit by the divisor.
- If the leftover after dividing the data unit by the divisor is zero, the unit data is not corrupted and may be accepted.
- If the leftover after dividing the data unit by the divisor is more than zero, the unit data is damaged and will be deleted.
Consider the following example with original data 11100 and divisor 1001.
- First, we'll add the zeros in the data unit section. The length of the divisor is four, and we know that the length of the string 0s is always one less than the length of its divisor.
- Therefore, we increase the data unit by three zeros, yielding 11100. The result of adding the zeros is 11100000, which we divide by the divisor, which is 1001. We use the binary division approach to divide data by divisor.
- The CRC remnant is the amount left behind after splitting the data unit by the divisor.
- The CRC remainder substitutes the extra string of 0s at the end of the data unit, and the final string sent across the network is 11100111.
CrcDemo.java:
// import required classes and packages
import java.io.*;
import java.util.*;
// creating CrcDemo class to illustrate the working of CRC (*Cyclic Redundancy Check)
class CrcDemo {
public static void main (String args []) {
// using Scanner Class object (* scan) to take user input
Scanner sc = new Scanner (System.in);
// declaring a size variable for data size.
int size;
// user input for data size.
System.out.println ("please enter a number for the size of the array: ");
size = sc.nextInt ();
// declaring the required data array
int dat [] = new int [size];
// take user input for data bits.
System.out.println ("please enter bits into the array : ");
for(int i = 0 ; i < size ; i++) {
System.out.println ("please enter bit " + (size-i) + ":");
dat [i] = sc.nextInt ();
}
// input the divisor size from the user
System.out.println ("please enter the divisor array size :");
size = sc.nextInt ();
// declaring divisor array
int divArray [] = new int [size];
System.out.println ("please enter div bits into the array : ");
for(int i = 0 ; i < size ; i++) {
System.out.println ("please enter bit " + (size-i) + ":");
divArray [i] = sc.nextInt ();
}
// Dividing input data with input divisor, store them in remdr array
int remdr [] = DataAndDivisorDivsion (dat, divArray);
for (int i = 0; i < remdr.length-1; i++) {
System.out.print (remdr [i]);
}
System.out.println ("\n CRC code that generated is: ");
for (int j = 0; j < dat.length; j++) {
System.out.print (dat [j]);
}
for (int k = 0; k < remdr.length-1; k++) {
System.out.print (remdr [k]);
}
System.out.println ();
// the size of the dataSent array with being equal to the sum of the data and the rem arrays length
int dataSent [] = new int[dat.length + remdr.length - 1];
System.out.println ("please enter bits needed to send into the array: ");
for (int i = 0; i < dataSent.length; i++) {
System.out.println ("please enter bit " + (dataSent.length - 1)+ ":");
dataSent [i] = sc.nextInt ();
}
recData (dataSent, divArray);
}
// creating DataAndDivisorDivsion () method to get Cyclic Redundancy Check
static int [] DataAndDivisorDivsion (int preDat [], int divArray []) {
// declaring remdr [] array
int remdr [] = new int [divArray.length];
int l;
int dat [] = new int [preDat.length + divArray.length];
// use the system's arraycopy () method for copying data into rem and data arrays
System.arraycopy (preDat, 0, dat, 0, preDat.length);
System.arraycopy (dat, 0, remdr, 0, divArray.length);
// iterate the preDat and exor the bits of the remainder and the divisor
for (l = 0; l < preDat.length; l++) {
System.out.println ((l+1) + ".) First data bit is : "+ remdr [0]);
System.out.print ("Remainder : ");
if (remdr [0] == 1) {
// exor the remainder bits with divisor bits
for (int j = 1; j < divArray.length; j++) {
remdr [j-1] = exOrOpertn (remdr [j], divArray [j]);
System.out.print (remdr [j-1]);
}
}
else {
// exor the remainder bits with 0
for (int j = 1; j < divArray.length; j++) {
remdr [j-1] = exOrOpertn (remdr [j], 0);
System.out.print (remdr [j-1]);
}
}
// The last bit of the remainder will be taken from the data
// This is the 'carry' taken from the dividend after every step
// of division
remdr [divArray.length-1] = dat [l + divArray.length];
System.out.println (remdr [divArray.length-1]);
}
return remdr;
}
// create exOrOpertn () method for exor operation on data
static int exOrOpertn (int x, int y) {
// returns exor of two bits
if (x == y) {
return 0;
}
return 1;
}
// method for received data
static void recData (int dat [], int divArray []) {
int remdr [] = DataAndDivisorDivsion (dat, divArray);
// Division complete
for (int j = 0; j < remdr.length; j++) {
if (remdr [j] != 0) {
// if the remainder is not zero, then the data is corrupted
System.out.println (" received Currupted data...");
return;
}
}
System.out.println ("Data received without any error.");
}
}
Output:

