Cyclic redundancy check in Python

Python Methods and Functions

What is CRC?
CRC or Cyclic Redundancy Check — it is a method of detecting random changes / errors in the communication channel.
CRC uses a generator polynomial that is available on both the sender and receiver sides. An example generator polynomial looks like x ^ 3 + 1. This generator polynomial represents the key 1001. Another example — x ^ 2 + x. this represents key 110.
Example:
Let the data be sent "EVN"
We are converting the string to binary string data.

input_string = "EVN"

 
# CONVERT string data to binary string data

data = (' ' .join (format (ord (x) , ' b') for x in input_string))

print (data)

 OUTPUT: 100010110101101001110 

CRC Key: 10 01
Code: CRC Key Length -1 - & gt; 000 appended at the end of the data.

 New data: 100010110101101001110000 Key: 1001 

We now apply CRC in socket programming on the sender and receiver sides.

Sender side

1. The task is to send the string data to the server / recipient side.
2. The sender sends a string, say "EVN".
3. First, this string is converted to a binary string. The key "100010110101101001110" is known to both the sender and the recipient, here the key is 1001.
4. This data is encoded using a CRC code using a client / sender key.
5. This encoded data is sent to the recipient.
6. The receiver later decodes the encoded data string to check if there was any error or not.

# Import socket module

import socket 

 

def xor (a, b):

 

# initialize result

result = []

  

  # Bypass all bits if bits

# same, then XOR is 0, otherwise 1

  for i in range ( 1 , len (b)):

if a [i] = = b [i]:

result.append ( '0' )

else :

result.append ( '1' )

  

return ' '.join (result)

  

  
# Performs modulo-2 division

def mod2div (divident, divisor):

 

  # The number of bits to be XORed at one time.

pick = len (divisor)

 

# Cutting the divider to the appropriate

# length for a specific step

tmp = divident [ 0 : pick]

 

while pick & lt; len (divident):

 

if tmp [ 0 ] = = '1' :

  

# replace the divisor with the result

# XOR and pull 1 bit down

  tmp = xor (divisor, tmp) + divident [pick]

 

else # If the leftmost bit is 0

 

# If the leftmost bit of the dividend (or

(the part used in each step) is 0, the step cannot

# use regular divisor; we need to use

# divider of all zeros.

tmp = xor ( '0' * pick, tmp) + divident [pick]

 

# increment selection to move on

pick + = 1

  

  # For the last n bits, we have to do this

# usually, as an increased peak value will cause

  # Index out of bounds.

if tmp [ 0 ] = = '1' :

  tmp = xor (divisor, tmp)

else :

tmp = xor ( '0' * pick, tmp)

 

checkword = tmp

return checkword

 
# Function used on the sender side to encode
# data by adding the remainder of the modular division
# at the end of the data.

def encodeData (data, key):

  

l_key = len (key)

 

# Adds zero- 1 zeros at the end of the data

appended_data = data + '0' * (l_key - 1 )

remainder = mod2div (appended_data, key)

  

# Add remainder in original data

codeword = data + remainder

return codeword 

 
# Create socket object

s = socket .socket () 

 
# Define the port you want to connect to

port = 12345  

 
# connect to the server on the local computer

s.connect (( '127.0.0.1' , port))

 
# Send data to the server & # 39; Hello world & # 39;

 
## s.sendall ("Hello World")

 

input_string = raw_input ( "Enter data you want to send- & gt;" )

# S.sendall (input_string)

data = (' '. join (format (ord (x), ' b') for x in input_string))

print data

key = "1001"

 

ans = encodeData (data, ke y)

print (ans)

s.sendall (ans)

 

 
# receive data from the server

print s.recv ( 1024 )

 
# close the connection
s.close ()

Receiver side

1. The receiver receives the encoded data string from the sender.
2. The receiver decodes the data using the key and finds out the remainder.
3. If the remainder is zero, it means that there are no errors in the data sent by the sender to the recipient.
4. If the remainder turns out to be non-zero, it means that an error has occurred, a negative acknowledgment is sent to the sender. The sender then resends the data until the receiver receives the correct data.

# First of all import the socket library

import socket

 

 

def xor (a, b):

 

# initialize the result

result = []

 

  # Bypass all bits if bits

  # same, then XOR is 0, otherwise 1

  for i in range ( 1 , len (b)):

if a [i] = = b [i]:

result.append ( '0' )

  else :

result.append ( ' 1' )

 

  return '' .join (result)

 

 
# Performs modulo-2

def mod2div (divident, divisor):

  

# The number of bits to be XORed at one time.

pick = len (divisor)

  

# Cutting the divider into the appropriate

  # length for a specific step

  tmp = divident [ 0 : pick]

 

while pick & lt; len (divident):

 

if tmp [ 0 ] = = '1' :

  

# replace the divisor with the result

# XOR and pull 1 bit down

tmp = xor (divisor, tmp) + divident [pick]

  

  else # If the leftmost bit is 0

# If the leftmost bit of the dividend (or

(the part used in each step) is 0, the step cannot

  # use normal divisor; we need to use

# divisor of all zeros.

  tmp = xor ( '0' * pick, tmp) + divident [pick]

 

# increment selection to move on

pick + = 1

 

# For the last n bits, we have to do this

# usually, since the increased peak value will call

# Index outside lami.

if tmp [ 0 ] = = '1' :

  tmp = xor (divisor, tmp)

else :

tmp = xor ( '0' * pick, tmp)

 

checkword = tmp

  return checkword

  
# Function used on the receiver side to decode
# data received by the sender

def decodeData (data, key):

 

l_key = len (key)

 

  # Adds zero-1 zeros to the end of the data

appended_data = data + ' 0' * (l_key - 1 )

remainder = mod2div (appended_data, key)

 

return remainder

 
# Create socket

s = socket.socket ()

print ( "Socket successfully created" )

  
# reserve a port on your computer in our
# happens 12345 but can be anything

port = 12345

  
s.bind (('', port))

print ( "socket binded to% s" % (port))

# put the socket on listen

s.listen ( 5 )

print ( "socket is listening" )

 

  

while True :

# Contact customer.

c, addr = s.accept ()

print ( 'Got connection from' , addr)

 

# Get data from client

data = c.recv ( 1024 )

 

print (data)

  

if not data:

break

 

key = "1001"

 

ans = decodeData ( data, key)

print ( "Remainder after decoding is- & gt;" + ans)

 

# If the remainder is all zeros, then oshi it didn't happen

temp = "0" * ( len (key) - 1 )

if ans = = temp:

c.sendall ( "THANK you Data - & gt;" + data + "Received No error FOUND" )

else :

c.sendall ( "Error in data" )

 

code class = "value"> 1 )

if ans = = temp:

c.sendall ( "THANK you Data - & gt;" + data + "Received No error FOUND" )

else :

  c.sendall ( "Error in data" )

 

code class = "value"> 1 )

if ans = = temp:

c.sendall ( "THANK you Data - & gt;" + data + "Received No error FOUND" )

else :

  c.sendall ( "Error in data" )