def shift(self, c, i=1): """Cyclic right shift of c using division (slide 11) """ Xi = X(i) # X^i polynomial XiCX = GF2.multPoly(Xi, c) # X^i * c(X) polynomial Xn1 = GF2.addPoly(X(self.n()), X(0)) # X^n + 1 polynomial ci = GF2.modPoly(XiCX, Xn1) # i times shifted c return padEnd(ci, self.n())
def shiftSyndrome(self, S, i=1): """Shift syndrome i times (slide 35) """ for i in range(0, i): # S1(X) = XS(X) mod g(X) S = GF2.modPoly(GF2.multPoly(X(1), S), self.g()) return S
def encode(m, g, systematic = True): if systematic: r = degree(g) # r = n - k Xr = X(r) # X^(n-k) XrmX = GF2.multPoly(Xr, m) # X^(n-k) * m(X) p = GF2.modPoly(XrmX, g) # p(X) = (X^(n-k) * m(X)) mod g(X) c = GF2.addPoly(p, XrmX) # c(X) = p(X) + (X^(n-k) * m(X)) else: c = GF2.multPoly(m, g) return c.astype(int)
def encode(m, g, systematic=True): """Encoding of cyclic code (in systematic form) (slide 23) ATTENTION: Dangling zeros in returned codeword are cut away. """ if systematic: r = degree(g) # r = n - k Xr = X(r) # X^(n-k) XrmX = GF2.multPoly(Xr, m) # X^(n-k) * m(X) p = GF2.modPoly(XrmX, g) # p(X) = (X^(n-k) * m(X)) mod g(X) c = GF2.addPoly(p, XrmX) # c(X) = p(X) + (X^(n-k) * m(X)) else: c = GF2.multPoly(m, g) return c.astype(int)
def decode(self, r, verbose=True): """Decode received polynomial r(X) using the Euclidean Algorithm. (slide 26) Args: r: received polynomial verbose: print the algorithm steps. """ GF = self.GF() if verbose: print() print('Decode the received polynomial:') print('r(X) = ' + self.GF().polyToString(r)) S = self.S(r, verbose) if verbose: print('The Euclidean algorithm is applied by constructing the ' + \ 'following table:') ri, ti = GF.HCF(X(2 * self.t()), S, verbose) lamb = GF.monicMultiplier(ti) errorLocationPoly = GF.multPoly(lamb, ti) errorLocationPolyDerivative = GF.derivePoly(errorLocationPoly) errorEvalutationPoly = GF.multPoly(lamb, ri) if verbose: print(u'An element \u03BB \u2208 GF(' + str(GF.q()) + ') is conveniently selected to multiply') print( u't_i(X) by, in order to convert it into a monic polynomial.') print(u'This value of \u03BB is \u03BB = ' + GF.elementToString(lamb)) print('Therefore:') print() print('Error location polynomial:') print(u'\u03C3(X) = \u03BB * t_i(X) = ' + GF.elementToString(lamb) + '(' + GF.polyToString(ti) + ')') print(' = ' + GF.polyToString(errorLocationPoly)) print() print(u'\u03C3\'(X) = ' + GF.polyToString(errorLocationPolyDerivative)) print() print('Error evaluation polynomial:') print(u'W(X) = -\u03BB * r_i(X) = ' + GF.elementToString(lamb) + ' * ' + GF.polyToString(ri)) print(' = ' + GF.polyToString(errorEvalutationPoly)) print() print( u'Performing Chien search in the error location polynomial \u03C3(X):' ) print() errorLocations = [] for i, root in enumerate(GF.roots(errorLocationPoly)): j = GF.elementToExp(GF.elementFromExp(-GF.elementToExp(root))) errorLocations.append(j) if verbose: print(u'\u03B1^(-j_' + str(i+1) + ') = ' + GF.elementToString(root) + \ '\t-> j_' + str(i+1) + ' = ' + str(j)) if verbose: print('\nError values:') errorValues = [] for i, errorLocation in enumerate(errorLocations): alpha = GF.elementFromExp(-errorLocation) res_W = GF.substituteElementIntoPoly(errorEvalutationPoly, alpha) res_o = GF.substituteElementIntoPoly(errorLocationPolyDerivative, alpha) errorValue = GF.divElements(res_W, res_o) errorValues.append(errorValue) if verbose: print('e_j' + str(i+1) + ' = W(' + GF.elementToString(alpha) + \ u') / \u03C3\'(' + GF.elementToString(alpha) + ') = ' + \ GF.elementToString(res_W) + \ ' / ' + GF.elementToString(res_o) + ' = ' + \ GF.elementToString(errorValue)) e = np.zeros(degree(r) + 1) for i, errorLocation in enumerate(errorLocations): errorValue = errorValues[i] e[errorLocation] = errorValue c = GF.addPoly(r, e) if verbose: print() print('Error polynomial:') print('e(X) = ' + GF.polyToString(e)) print() print('Code vector:') print('c = r + e = ' + str(c)) return c.astype(int)