7. Write a program
for error detecting
code using CRC-CCITT (16- bits).
Whenever digital data is stored or interfaced, data corruption might occur. Since the beginning of computer
science, developers have been thinking
of ways to deal with this type of problem. For serial data they came up with the solution to attach a parity bit to each sent byte. This simple detection
mechanism works if an odd number of bits in a byte changes, but an even number of false bits in one byte will not be detected
by the parity check. To overcome this problem developers have searched for mathematical sound mechanisms to detect
multiple false bits. The CRC calculation or cyclic redundancy check was the result of this. Nowadays CRC calculations are used in all types of communications. All packets
sent over a network
connection are checked
with a CRC. Also each data block on your hard
disk has a CRC
value attached to it. Modern computer world cannot do without these CRC
calculations. So let's see why they are so widely used. The answer is simple; they are powerful, detect many types of errors and are extremely fast to calculate
especially when dedicated hardware chips are used.
The idea behind CRC calculation is to look at the data as one large binary number. This number is divided by a certain value and the remainder
of the calculation is called the CRC. Dividing in the CRC calculation at first looks to cost a lot of computing power, but it can be performed very quickly if we use
a method similar to the one learned at school. We will
as an example calculate
the remainder for the character 'm'—which is 1101101 in binary notation— by dividing
it by 19 or 10011. Please note that 19 is an odd number.
This is necessary as we will see further on. Please refer to your schoolbooks as the binary calculation method here is not very different from the decimal method you learned when you were young. It might only look a little bit strange.
Also notations differ between countries, but the method
is similar.

With decimal calculations
you can quickly check that 109 divided
by 19 gives a quotient of 5 with 14 as the remainder. But what we also see in the scheme is that every bit extra to check only costs one binary comparison and in 50% of the cases one binary
subtraction. You can easilyincrease the number of bits of the test data string—for example to 56 bits if we use our example
value "Lammert"—and the result can be calculated with 56 binary
comparisons and an average of 28 binary
subtractions. This can be implemented in hardware directly with only very few transistors involved. Also software algorithms can be very efficient.
All of the CRC formulas you will encounter are simply checksum algorithms based on modulo-2
binary division
where we ignore carry bits and in effect the subtraction will be equal to an exclusive or operation. Though some differences exist in the specifics
across different
CRC formulas, the basic mathematical process is always
the same:
·
The
message bits are appended
with c zero bits; this augmented message is the dividend
·
A
predetermined c+1-bit binary
sequence, called
the
generator polynomial, is the divisor
·
The checksum
is the c-bit remainder
that results from the division operation
Table 1
lists some of the most commonly used generator polynomials
for 16- and 32-bit CRCs. Remember
that the width of
the divisor is always one bit wider than
the remainder. So, for example, you’d
use a 17-bit generator polynomial whenever
a 16-bit checksum is required.
CRC-CCITT
|
CRC-16
|
CRC-32
|
|
Checksum Width
|
16 bits
|
16 bits
|
32 bits
|
Generator Polynomial
|
10001000000100001
|
11000000000000101
|
100000100110000010001110110110111
|
International Standard CRC Polynomials
SOURCE CODE:
package crc;
import
java.util.Scanner;
public class
CRC {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n;
//Accept the input
System.out.println("Enter the size
of the data:");
n = scan.nextInt();
int data[] = new int[n];
System.out.println("Enter the
data, bit by bit:");
for (int i = 0; i < n; i++) {
data[i] = scan.nextInt();
}
// Accept the divisor
System.out.println("Enter the size
of the divisor:");
n = scan.nextInt();
int divisor[] = new int[n];
System.out.println("Enter the
divisor, bit by bit:");
for (int i = 0; i < n; i++) {
divisor[i] = scan.nextInt();
}
// Divide the
input data by the input divisor
// Store the remainder that is returned
by the method
int remainder[] = divide(data,
divisor);
/*System.out.print("Remainder
is:");
for(int i=0 ; i <
remainder.length-1 ; i++) {
System.out.print(remainder[i]);
}
System.out.println();
*/
System.out.println("\nThe CRC code
generated is:");
for (int i = 0; i < data.length;
i++) {
System.out.print(data[i]);
}
for (int i = 0; i < remainder.length
- 1; i++) {
System.out.print(remainder[i]);
}
System.out.println();
// Create a new
array
// It will have the remainder generated
by the above method appended
// to the input data
int sent_data[] = new int[data.length +
remainder.length - 1];
System.out.println("Enter the data
to be sent, bit by bit:");
for (int i = 0; i <
sent_data.length; i++) {
sent_data[i] = scan.nextInt();
}
receive(sent_data, divisor);
}
static int[] divide(int old_data[], int
divisor[]) {
int remainder[], i;
int data[] = new int[old_data.length +
divisor.length];
System.arraycopy(old_data, 0, data, 0,
old_data.length);
// Remainder array stores the remainder
remainder = new int[divisor.length];
// Initially, remainder's bits will be
set to the data bits
System.arraycopy(data, 0, remainder, 0,
divisor.length);
// Loop runs for
same number of times as number of bits of data
//
This loop will continuously xor the bits of the remainder and divisor
for (i = 0; i < old_data.length;
i++) {
if
(remainder[0] == 1) {
// We have to xor the remainder
bits with divisor bits
for (int j = 1; j <
divisor.length; j++) {
remainder[j - 1] =
remainder[j] ^ divisor[j];
}
} else {
// We have to xor the remainder
bits with 0
for (int j = 1; j <
divisor.length; j++) {
remainder[j - 1] =
remainder[j] ^ 0;
}
}
//
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
remainder[divisor.length - 1] = data[i +
divisor.length];
}
return remainder;
}
static void receive(int data[], int
divisor[]) {
// This is the
receiver method
// It accepts the data and divisor
(although the receiver already has
// the divisor value stored, with no
need for the sender to resend it)
int remainder[] = divide(data,
divisor);
// Division is done
for (int i = 0; i <
remainder.length; i++) {
if (remainder[i] != 0) {
// If remainder is not zero
then there is an error
System.out.println("There
is an error in received data...");
return;
}
}
//Otherwise there is no error in the
received data
System.out.println("Data was
received without any error.");
}
}
/*NOTE:
System.arraycopy()
method copies a source array from a specific beginning position
to the
destination array from the mentioned position.
No. of
arguments to be copied are decided by len argument.
public
static void arraycopy(Object source_arr, int sourcePos,
Object dest_arr,
int destPos, int len)
Parameters :
source_arr :
array to be copied from
sourcePos :
starting position in source array from where to copy
dest_arr :
array to be copied in
destPos :
starting position in destination array, where to copy in
len : total
no. of components to be copied.
*/
No comments:
Post a Comment