Advertisement
makispaiktis

Hamming Code Error Correction

May 6th, 2022 (edited)
1,320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.33 KB | None | 0 0
  1. from math import log2
  2. from random import randrange
  3. import copy
  4.  
  5. # Function 1 ---> 2^r >= m + r + 1
  6. def find_r(m):
  7.     r = 0
  8.     while 2**r - r < m + 1:
  9.         r = r + 1
  10.     return r
  11.  
  12. # Function 2 - Decimal to binary
  13. def dec_to_bin(decimal):
  14.     # decimal = INTEGER
  15.     if decimal == 0:
  16.         return [0]
  17.     else:
  18.         digits = list()
  19.         LEN = int(log2(decimal)) + 1
  20.         for exp in range(LEN-1, -1, -1):
  21.             value = 2 ** exp
  22.             if decimal >= value:
  23.                 digits.append(1)
  24.                 decimal -= value
  25.             else:
  26.                 digits.append(0)
  27.         return digits
  28.  
  29.  
  30. # Function 3 - Binary to decimal
  31. def bin_to_dec(binary):
  32.     # binary = LIST
  33.     SUM = 0
  34.     LEN = len(binary)
  35.     for index in range(LEN):
  36.         SUM += binary[index] * (2**(LEN-1-index))
  37.     return SUM
  38.  
  39.  
  40. # Function 4 - Padding with zeros
  41. def pad_zeros(binary, LEN):
  42.     LEN1 = int(log2(LEN)) + 1
  43.     LEN2 = len(binary)
  44.     binary2 = [0 for i in range(LEN1 - LEN2)]
  45.     binary = binary2 + binary
  46.     return binary
  47.  
  48.  
  49. # Function 5 - Binary representation of indeces
  50. def bin_representation(LEN):
  51.     # If LEN = 11, I will create a list with all the binary representations of numbers
  52.     # between 11 and 1 (inclusively)
  53.     indeces_binary = list()
  54.     for i in range(LEN, 0, -1):
  55.         binary = dec_to_bin(i)
  56.         indeces_binary.append(pad_zeros(binary, LEN))
  57.     return indeces_binary
  58.  
  59.  
  60.  
  61. # Function 6 - Write the codeword without redundant bits
  62. def write_codeword_no_redundant(data, m, r, LEN):
  63.     # I will symbolize redundant with the number '-1'
  64.     codeword_no_redundant = list()
  65.     counter = 0
  66.     for i in range(LEN, 0, -1):
  67.         if log2(i) == int(log2(i)):
  68.             codeword_no_redundant.append(-1)
  69.         else:
  70.             codeword_no_redundant.append(data[counter])
  71.             counter += 1
  72.     return codeword_no_redundant
  73.  
  74.  
  75.  
  76. # Function 7 - Parity bits
  77. def determine_parity(codeword_no_redundant, m, r, LEN, indeces_binary):
  78.     # There will be 'r' parity bits in the word
  79.     # print()
  80.     par_bits = list()
  81.     par_bits_check_pos = list()
  82.     for par_exp in range(r):
  83.         # print("par_exp = ", par_exp)
  84.         # r = 4, par_exp = (0, 1, 2, 3)
  85.         # Assuming r = 2, check the 2nd position (index 1) from binary representation of indeces
  86.         pos_check = r - 1 - par_exp
  87.         # I will check how many 1's are there in positions with index pos_check
  88.         SUM = 0
  89.         par_exp_check_pos = list()
  90.         for i in range(len(indeces_binary)):
  91.             index_binary = indeces_binary[i]
  92.             if index_binary[pos_check] == 1:
  93.                 par_exp_check_pos.append(bin_to_dec(index_binary))
  94.                 # print(bin_to_dec(index_binary))
  95.                 value = codeword_no_redundant[i]
  96.                 # print("Value = ", value)
  97.                 if value != -1:
  98.                     SUM += value
  99.         # SUM IS OK by now
  100.         # print("SUM = ", SUM)
  101.         par_bits_check_pos.append(par_exp_check_pos)
  102.         par_bit = SUM % 2
  103.         par_bits.append(par_bit)
  104.         # print()
  105.     # Now, I have to flip my list with parity bits
  106.     par_bits.reverse()
  107.     par_bits_check_pos.reverse()
  108.     return par_bits, par_bits_check_pos
  109.  
  110.  
  111.  
  112. # Function 8 - Fill with parity bits
  113. def fill_with_parity(codeword_no_redundant, par_bits):
  114.     codeword = copy.deepcopy(codeword_no_redundant)
  115.     counter = 0
  116.     for i in range(len(codeword)):
  117.         if codeword[i] == -1:
  118.             codeword[i] = par_bits[counter]
  119.             counter += 1
  120.     return codeword, codeword_no_redundant
  121.  
  122.  
  123.  
  124.  
  125. # Function 9 - Hamming coded data message
  126. def Hamming_in_data(data):
  127.     # 1. Initialization of parameters
  128.     r = find_r(m)
  129.     LEN = m + r         # Codeword length
  130.     # 2. Codeword without redundant
  131.     codeword_no_redundant = write_codeword_no_redundant(data, m, r, LEN)
  132.     # 3. Determine the missing positions of a codeword = message + redundant
  133.     indeces_binary = bin_representation(LEN)
  134.     par_bits, par_bits_check_pos = determine_parity(codeword_no_redundant, m, r, LEN, indeces_binary)
  135.     # 4. Fill the gaps (-1) in codeword with this list
  136.     codeword, codeword_no_redundant = fill_with_parity(codeword_no_redundant, par_bits)
  137.     return codeword_no_redundant, par_bits, par_bits_check_pos, codeword
  138.  
  139.  
  140.  
  141. # Function 10 - Error detection and correction
  142. def error_correction(codeword, indeces, LEN):
  143.     digits = list()
  144.     for i in range(len(indeces)):
  145.         index = indeces[i]
  146.         SUM = 0
  147.         for j in range(len(index)):
  148.             index_check = LEN - index[j]
  149.             SUM += codeword[index_check]
  150.         digits.append(SUM % 2)
  151.     return digits
  152.  
  153.  
  154.  
  155. # Function 11 - Simulate Hamming Error Correction
  156. def Hamming_correct(data, codeword_no_redundant, par_bits, par_bits_check_pos, codeword):
  157.     LEN = len(codeword)
  158.     print()
  159.     print(120 * "*")
  160.     print(" Lengths =  " + str(len(data)) + ", " + str(len(par_bits)) + ", " + str(len(codeword)))
  161.     print("    Data =  " + str(data))
  162.     # print("No_redun =  " + str(codeword_no_redundant))
  163.     print("Par_bits =  " + str(par_bits))
  164.     print("Codeword =  " +  str(codeword))
  165.     # Suppose in receiver there is a single error in a single index of the codeword sent
  166.     # So, in 'index_error', the '0' becomes '1' and the '1' becomes '0'
  167.     # 0 ---> 1 or 1 ---> 0 by this way: rec = 1 - tr
  168.     index_error = randrange(LEN)
  169.     codeword[index_error] = 1 - codeword[index_error]
  170.     # print()
  171.     print("------> Error in position " + str(LEN - index_error) + " from the right (index " + str(index_error) + ") <------")
  172.     print("Received = ", codeword)
  173.     # print("Indeces to be checked = " + str(par_bits_check_pos))
  174.     # Now, I have the received message containing a single error. I follow the appropriate process for error detection
  175.     digits = error_correction(codeword, par_bits_check_pos, LEN)
  176.     digits_str = [str(element) for element in digits]
  177.     print("------> Error occured in position " + ''.join(digits_str) + " = " + str(bin_to_dec(digits)) + " <------")
  178.     print(120 * "*")
  179.  
  180.  
  181.  
  182. # MAIN FUNCTI0N
  183. low = 10
  184. high = 20
  185. m = randrange(low, high + 1)
  186. data = [randrange(2) for i in range(m)]
  187. codeword_no_redundant, par_bits, par_bits_check_pos, codeword = Hamming_in_data(data)
  188. Hamming_correct(data, codeword_no_redundant, par_bits, par_bits_check_pos, codeword)
  189.  
  190.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement