Download .ipynb file

!pip install :

In [3]:
!pip install bitarray==1.2.0
Collecting bitarray==1.2.0
  Downloading https://files.pythonhosted.org/packages/eb/fd/bf67cfea810305148ab8a1e8fbdcc5179f56979c73907fec9a36ebd4a58a/bitarray-1.2.0.tar.gz (48kB)
     |████████████████████████████████| 51kB 2.7MB/s 
Building wheels for collected packages: bitarray
  Building wheel for bitarray (setup.py) ... done
  Created wheel for bitarray: filename=bitarray-1.2.0-cp36-cp36m-linux_x86_64.whl size=105082 sha256=5cb0c936788febbd05c64a93c22c42cadef846f50aa3bbc9951e949729685412
  Stored in directory: /root/.cache/pip/wheels/7d/74/a0/a16a871bce5b38a192b8a529805d69abd4a28745ea31bc2ff1
Successfully built bitarray
Installing collected packages: bitarray
Successfully installed bitarray-1.2.0
In [4]:
!pip install termcolor
Requirement already satisfied: termcolor in /usr/local/lib/python3.6/dist-packages (1.1.0)

Practical Work 2-1 :

In [5]:
import os
from bitarray import bitarray, bitdiff
from IPython.display import clear_output
import termcolor
class color:
  RED = '\033[91m'
  END = '\033[0m'

H3 = [
        bitarray('110'),
        bitarray('101'),
        bitarray('011'),
        bitarray('111'),
        bitarray('100'),
        bitarray('010'),
        bitarray('001')
      ]

G3 = [
        bitarray('1000110'),
        bitarray('0100101'),
        bitarray('0010011'),
        bitarray('0001111')
      ]

def Encoder(msg):
    k = 0
    coded = bitarray()
    x = bitarray(msg)
    if len(x)%4 != 0:
        print('Ops! The length must be a divisible by 4 without remainder')
        return None
    while k is not len(x):
        x1 = x[k:k+4]
        for i in range(0,7):
            coded.append(False)
            for j in range(0,4):
                coded[len(coded)-1] ^= x1[j]&G3[j][i]
        k += 4
    return coded
        
def Decoder(msg):
    k = 0
    x = bitarray(msg)
    decoded = bitarray()
    if len(x)%7 != 0:
        print('Ops! The length must be a divisible by 7 without remainder')
        return None
    while k != len(x):
        x1 = x[k:k+7]

        s = bitarray()
        for i in range(0,3):
            s.append(False)
            for j in range(0,7):
                s[len(s)-1] ^= x1[j]&H3[j][i]
        if s.to01() == '000': #error - false
            decoded += x1[:4]
        else: #error true
            for i in range(0,7):
                if bitdiff(H3[i], s) == 0:
                    #print("errored bit: " + str(i))
                    x1[i] = not x1[i] #flip errored bit
            decoded += x1[:4]
        k = k+7
    return decoded

def G3xH3():
    R = [bitarray('0000000') for i in range(0,4)]
    for i in range(0,4):
        for j in range(0,3):
            s=False
            for k in range (0,7):
                s ^= G3[i][k]&H3[k][j]
            R[i][j] = s
    if R[i][j] != False:
        return False
    print('G3xH3=')
    for ba in R:
        print('\t'+ba.to01())

    return True   

def allPossibleErrors(message, message_length):
#displaying all kinds of errors in the word and identifying the original
    coded = Encoder(message)
    print('Message: ', message)
    print('Coded: ', coded)
    #Adding errors
    colorBin = ""
    count = 0
    for i in range(0, len(coded)):
        y = coded.copy()
        y[i] = not y[i]
        decoded = Decoder(y)
        if decoded != coded[:4]:
            print('Decoded is not equal to coded')
            return False
            #print(color.RED + 'Hello World!' + color.END)
        print('\tError at '+color.RED+ str(i) +color.END+' position: ' + y.to01() +' decoded as:' + decoded.to01())

        '''colorBin = y.to01()
    for k in range(0,len(colorBin)):
      if k==1:
        print('\n k:',k)
        print('\tError at '+color.RED+ str(i) +color.END+' position: ' + y.to01() +' decoded as:' + decoded.to01())
        #print('\tError at ' + str(k) + ': ' + colorBin.replace(str(colorBin[k]), termcolor.colored(str(colorBin[k]), 'red')) +' decoded as:')
      #count +=1'''

    return True

def Evaluate(message_length=4, msg=bitarray()):
    msg = bitarray(msg)
    if len(msg) == message_length:
        evaluation = allPossibleErrors(msg, message_length)
        if evaluation:
            print('\nOriginal message while an error existing anywhere: \n', msg.to01())
        else:
            print('\nError while decoding for word: ', msg.to01())
        return
    for k in [False,True]:
        msg.append(k)
        evaluate(message_length, msg)
        msg.pop()

def PracticalWork_2_1():
    menu = '(1) Encode\n(2) Decode\n(3) Evaluate\n(4) Check if G3xH3 is null\n(0) Return to Program Selection'
    print(menu)
    while True:
        choice = input('\nEnter your choice: ')
        choice = int(choice)
        if choice not in range(0,5):
            clear_output()

            print('Ops! it\'s a wrong choice ')
            print('Please try again:\n')
            print(menu)
        elif choice == 0:
          clear_output()
          ProgramSelection()
          break
        if choice == 1:
          try:
            x = input('Enter a message in binary to encode: ')
            for i in x:
                if i in '10': # If digit is 1 or 0
                    binary = True
                else:
                    binary = False
                    break
            if binary == False:
                print('Ops! please enter a message in binary numbers')
          except ValueError:
            print(menu)
          c = Encoder(x)
          if type(c) is bitarray:
              print('Encoded message: ', c.to01())
        elif choice == 2:
            y = input('Enter a encoded message to decode: ')
            x = Decoder(y)
            if type(x) is bitarray:
                print('decoded msg: ', x.to01())
        elif choice == 3:
            msg = input('Enter a message in binary (4 bit) to encode: ')
            evaluate(4,msg)
            
        elif choice == 4:
            if G3xH3():
                print('G3xH3 is a null matrix')
            else:
                print('G3xH3 is not a null matrix')


#main()

Practical Work 3.1 :

In [6]:
from os import system
from bitarray import bitarray

#coef. for F8 ax^2+bx+c

def F8Table():
    coef = [
        bitarray([0,0,0]),
        bitarray([0,0,1]),
        bitarray([0,1,0]),
        bitarray([0,1,1]),
        bitarray([1,0,0]),
        bitarray([1,0,1]),
        bitarray([1,1,0]),
        bitarray([1,1,1])
    ]
    F8 = []
    for i in range(0,8):
        F8.append([])
        for j in range(0,8):
            F8[i].append(coef.index(coef[i]^coef[j]))
    return F8

#coef. F2^8
def Generating_of_Coef(m=8, c=bitarray(), res=[]):
    if len(c) == m:
        res.append(c.copy())
        return res
    for bit in [False, True]:
        c.append(bit)
        Generating_of_Coef(m,c,res)
        c.pop()
        if len(res) == pow(2,m):
            return res

def F256Table():
    coef = Generating_of_Coef()
    F256 = []

    #print(len(coef))

    for i in range(0,256):
        F256.append([])
        for j in range(0, 256):
            F256[i].append(coef.index(coef[i]^coef[j]))
    return F256  

def PracticalWork_3_1():
    menu = '(1) F8 table\n(2) F256 table\n(3) Clear\n(0) Return to Program Selection'
    print(menu)
    while True:
        choice = input('\nEnter your choice:')
        choice = int(choice)
        if choice not in range(0,4):
            clear_output()
            print('Ops! it\'s a wrong choice ')
            print('Please try again:\n')
            PracticalWork_3_1()
            break
            
        elif choice == 0:
          clear_output()

          ProgramSelection()
          break
          
        if choice == 1:
            F8 = F8Table()
            for row in F8:
                print(row)
        elif choice == 2:
            F256 = F256Table()
            for row in F256:
                print(row)

        elif choice == 3:
            clear_output()
            print(menu)
        

#main()

Theory and Engineering of Information Transfer

Following program code is for finding a cyclic generator polynomial when dividing the binomial x-1 without remainder

some theory: Cyclic codes are a branch of error-correcting coding theory that demonstrates a fruitful combination of mathematical elegance and practical utility. If the code is cyclic and the vector

U = (U0,U1,...,Un−1) belongs to the code, then the vector

U* = (Un−1,U0,U1,...,Un−2) also belongs to the code.

The spectrum of the code is the set of weights w of allowed codewords s with the corresponding list indicating the number of scales. In other words, the spectrum of the code is a dictionary {weight: quantity}.

In [7]:
import sympy as sy
import itertools as it
from sympy.parsing.sympy_parser import parse_expr
from sympy.abc import x
import re
from collections import Counter
from functools import reduce
import random
def pol(n):
    dl = list(sy.factor(x ** n - 1, modulus=2).args)
    return dl


def por_pol(dpor, r):
    d2 = set()
    d3 = list()
    for urav in dpor:
        if str(urav).find(')**') > 0:
            for i in range(int(str(urav)[-1])):
                new = parse_expr(str(urav)[1:-4])
                d3.append(new)
    if d3:
        dpor = d3
    for k_urav in range(1, len(dpor) + 1):
        for i in it.combinations(dpor, k_urav):
            z = reduce(lambda o, y: sy.expand(o * y, modulus=2), i)
            d2.add(z)
    d2 = list(d2)
    if int(r) == 1:
        costill = list(d2[x] for x in range(0, int(r)))
        print(costill, 'All generating polynomials of degree r')
        return costill, costill
    else:
        ii = list(filter(lambda x: x[4:4 + len(r)] == r and x[4 + len(r)] == ' ',
                         str(d2).split(',')))
        d_dopo = list(
            int(str(d2).split(',').index(ii[x])) for x in
            range(len(ii)))
        D_por = list(d2[x] for x in d_dopo)
        print(D_por, 'All generating polynomials of degree r for clarity')
        return D_por[0], D_por


def matrixx(pp, n, r):
    d3 = list()
    Pol_urav = list()
    xst = 1
    for i in range(n - int(r)):
        line_list = (re.sub(' ', '', str(sy.expand(pp * xst))).split('+'))
        d3.append(sorted(line_list))
        Pol_urav.append(sy.expand(pp * xst))
        xst *= x
    d_buf = list()
    for i in range(n - int(r)):
        x1st = 1
        now = []
        for ii in range(n):
            now.append(str(x1st))
            x1st *= x
        d_buf.append(now)
    for i in range(n - int(r)):
        d_plus = set(d_buf[i]) & set(d3[i])
        ie = 0
        for ii in d_plus:
            d_buf[i][d_buf[i].index(ii)] = 1
        for ii in range(n):
            if d_buf[i][ie] != 1:
                d_buf[i][ie] = 0
                ie += 1
            else:
                ie += 1
    Pol_urav.append(0)
    return d_buf


def PoiskminPol(ishnpol, n, r):
    z1z = list(list(Spetr(ishnpol[x], n, r) for x in range(len(ishnpol))))
    d_mincod = list((list(z1z[x].keys())[1]) for x in range(len(ishnpol)))
    print(d_mincod, 'MIN d for polynomials of degree r')
    iskPoly = ishnpol[d_mincod.index(max(d_mincod))]
    return iskPoly, z1z[d_mincod.index(max(d_mincod))]


def provepolinom(Porpolinom, n):
    provpol = sy.factor((x ** n - 1) * Porpolinom ** -1, modulus=2)
    return sy.expand(provpol, modulus=2)


def Spetr(Porpolinom, n, r):
    d_buf = list()
    x1st = 1
    for i in range(n - int(r)):
        d_buf.append(x1st)
        x1st *= x
    U = list()
    for i in range(1, n - int(r)):
        vrcomb = list(it.combinations(d_buf, i))
        for ii in vrcomb:
            if str(ii)[-2::] == ',)':
                U.append(sy.expand(parse_expr(str(ii)[1:-2]) * Porpolinom, modulus=2))
            else:
                zz1 = '+'.join(str(ii).split(','))
                U.append(sy.expand(parse_expr(str(zz1)) * Porpolinom, modulus=2))
    U.append(sy.expand(parse_expr('+'.join(str(d_buf)[1:-1].split(','))) * Porpolinom, modulus=2))
    xxx = list(str(str(ico).count('+') + 1) for ico in U)
    sspectr = {'0': 1}
    coount = Counter(xxx)
    sspectr.update(coount)
    ssss = dict()
    for key in sorted(sspectr, key=lambda i: int(i)):
        ssss.update({int(key): sspectr[key]})
    return ssss
def PolynomialGenerator():
#Selection advisor{
  n_list = [10,14, 15]
  r_list = [4,6,8]
  n=random.choice(n_list)
  r=random.choice(r_list)
#}

  print('Enter n as code length (f.e. set n as ',n,'):')
  nn = int(input())
  print('Enter r as number of check characters (f.e. set r as ',r,'):')
  rr = input()
  dl = pol(nn)
  print(dl)
  pp1, D_porvse = por_pol(dl, rr)
  maxcodpoly, spectal = PoiskminPol(D_porvse, nn, rr)
  print(maxcodpoly, 'generator polynomial')

  por_mat = matrixx(maxcodpoly, nn, rr)
  for i in por_mat:
    print(i)
  ProvP = provepolinom(maxcodpoly, nn)
  print(ProvP, 'checking polynomial')
  print(spectal, 'Code spectrum\n')

def finding_a_cyclic_generator_polynomial():

  while True:
    menu = '(1) Run the program\n(0) Return to main menu'
    print(menu)
    choice = input('\nEnter your choice:')
    choice = int(choice)
    if choice not in range(0,2):
      clear_output()
      print('Ops! it\'s a wrong choice\nPlease try again:\n')
      finding_a_cyclic_generator_polynomial()
      break
    elif choice == 0:
      clear_output()
      ProgramSelection()
      break

    if choice == 1:
      clear_output()
      PolynomialGenerator()

The main menu of the program

In [8]:
def ProgramSelection():
  #clear_output()
  menu = print('(1) Practical Work 2.1\n(2) Practical work 3.1\n(3) Finding a cyclic generator polynomial\n(0) Exit program')
  choice = int(input('\nEnter your choice:'))
  if choice == 0:
    clear_output()
    exit 
    
  elif choice == 1:
    clear_output()
    PracticalWork_2_1()
  elif choice == 2:
    clear_output()
    PracticalWork_3_1()
  elif choice == 3:
    clear_output()
    finding_a_cyclic_generator_polynomial()

  if choice not in range(0,4):
            clear_output()

            print('Ops! it\'s a wrong choice ')
            print('Please try again:\n')

            print(menu)
            ProgramSelection()

ProgramSelection()