// Top level decoder module void rs_decode (unsigned char n, unsigned char t, unsigned char in_d[nn], unsigned char *k, unsigned char out_d[kk]) { unsigned char temp_k = n - 2*t; unsigned char s[2*tt]; unsigned char c[tt+2]; unsigned char w[tt+2]; unsigned char lambda[tt]; unsigned char omega[tt]; unsigned char err_no; unsigned char err_loc[kk]; unsigned char alpha_inv[tt]; unsigned char err[kk]; unsigned char in_data[kk]; unsigned char in_d_2[nn]; Simple_rs1: for (int i = 0; i < nn; i++) in_d_2[i] = in_d[i]; *k = temp_k; rs_fifo(temp_k, in_d, in_data); syndrome(temp_k, t, in_d_2, s); berlekamp(t, s, lambda, omega); chien_search(kk, tt, lambda, &err_no, err_loc, alpha_inv); error_mag(kk, lambda, omega, err_no, err_loc, alpha_inv, err); error_correct(temp_k, in_data, err, out_d); }
void Hamming_Code::decode(const bvec &coded_bits, bvec &decoded_bits) { int length = coded_bits.length(); int Itterations = floor_i(static_cast<double>(length) / n); ivec Hindexes(n); bvec temp(n - k); bvec coded(n), syndrome(n - k); int isynd, errorpos = 0; int i, j; decoded_bits.set_size(Itterations*k, false); for (i = 0; i < n; i++) { for (j = 0; j < n - k; j++) temp(j) = H(j, i); Hindexes(i) = bin2dec(temp); } //Decode all codewords for (i = 0; i < Itterations; i++) { coded = coded_bits.mid(i * n, n); syndrome = H * coded; isynd = bin2dec(syndrome); if (isynd != 0) { for (j = 0; j < n; j++) if (Hindexes(j) == isynd) { errorpos = j; }; coded(errorpos) += 1; } decoded_bits.replace_mid(k*i, coded.right(k)); } }
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) { Ref<GenericGFPoly> poly(new GenericGFPoly(field, received)); #ifdef DEBUG cout << "decoding with poly " << *poly << "\n"; #endif ArrayRef<int> syndromeCoefficients(new Array<int> (twoS)); #ifdef DEBUG cout << "syndromeCoefficients array = " << syndromeCoefficients.array_ << "\n"; #endif bool dataMatrix = (field.object_ == GenericGF::DATA_MATRIX_FIELD_256.object_); bool noError = true; for (int i = 0; i < twoS; i++) { int eval = poly->evaluateAt(field->exp(dataMatrix ? i + 1 : i)); syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return; } Ref<GenericGFPoly> syndrome(new GenericGFPoly(field, syndromeCoefficients)); Ref<GenericGFPoly> monomial = field->buildMonomial(twoS, 1); vector<Ref<GenericGFPoly> > sigmaOmega = runEuclideanAlgorithm(monomial, syndrome, twoS); ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]); ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations, dataMatrix); for (unsigned i = 0; i < errorLocations->size(); i++) { int position = received->size() - 1 - field->log(errorLocations[i]); //TODO: check why the position would be invalid if (position < 0 || (size_t)position >= received.size()) throw IllegalArgumentException("Invalid position (ReedSolomonDecoder)"); received[position] = GenericGF::addOrSubtract(received[position], errorMagitudes[i]); } }
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) { Ref<GF256Poly> poly(new GF256Poly(field, received)); #ifdef DEBUG cout << "decoding with poly " << *poly << "\n"; #endif ArrayRef<int> syndromeCoefficients(new Array<int>(twoS)); #ifdef DEBUG cout << "syndromeCoefficients array = " << syndromeCoefficients.array_ << "\n"; #endif bool noError = true; for (int i = 0; i < twoS; i++) { int eval = poly->evaluateAt(field.exp(i)); syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return; } Ref<GF256Poly> syndrome(new GF256Poly(field, syndromeCoefficients)); Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1)); vector<Ref<GF256Poly> > sigmaOmega (runEuclideanAlgorithm(monomial, syndrome, twoS)); ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]); ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations); for (unsigned i = 0; i < errorLocations->size(); i++) { int position = received->size() - 1 - field.log(errorLocations[i]); received[position] = GF256::addOrSubtract(received[position], errorMagitudes[i]); } }
/* * Full implementation of the three error correcting Peterson decoder. For * t<6, it is faster than Massey - Berlekamp. It is also somewhat more * intuitive. */ extern void ecc_decode(uint8_t code[ECC_CAPACITY], uint8_t mesg[ECC_CAPACITY], int *errcode) { REVERSE(code, ECC_CAPACITY); uint8_t syn[ECC_OFFSET + 1], deter, z[4], e0, e1, e2, n0, n1, n2, w0, w1, w2, x0, x[3]; int sols; *errcode = 0; /* * First, get the message out of the code, so that even if we can't correct * it, we return an estimate. */ for (int i = 0; i < ECC_PAYLOAD; i++) mesg[i] = code[(ECC_CAPACITY - 1) - i]; syndrome(code, syn); if (syn[0] == 0) return; /* * We now know we have at least one error. If there are no errors detected, * we assume that something funny is going on, and so return with errcode 4, * else pass the number of errors back via errcode. */ errnum(syn, &deter, errcode); if (*errcode == 4) return; /* Having obtained the syndrome, the number of errors, and the determinant, * we now proceed to correct the block. If we do not find exactly the * number of solutions equal to the number of errors, we have exceeded our * error capacity, and return with the block uncorrected, and errcode 4. */ switch (*errcode) { case 1: x0 = GF_MUL(syn[2], GF_INV(syn[1])); w0 = GF_MUL(GF_EXP(syn[1], 2), GF_INV(syn[2])); if (v2e[x0] > 5) mesg[(ECC_CAPACITY - 1) - v2e[x0]] = GF_ADD(mesg[(ECC_CAPACITY - 1) - v2e[x0]], w0); return; case 2: z[0] = GF_MUL(GF_ADD(GF_MUL(syn[1], syn[3]), GF_EXP(syn[2], 2)), GF_INV(deter)); z[1] = GF_MUL(GF_ADD(GF_MUL(syn[2], syn[3]), GF_MUL(syn[1], syn[4])), GF_INV(deter)); z[2] = 1; z[3] = 0; polysolve(z, x, &sols); if (sols != 2) { *errcode = 4; return; } w0 = GF_MUL(z[0], syn[1]); w1 = GF_ADD(GF_MUL(z[0], syn[2]), GF_MUL(z[1], syn[1])); n0 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[0])]; n1 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[1])]; e0 = GF_MUL(GF_ADD(w0, GF_MUL(w1, x[0])), GF_INV(z[1])); e1 = GF_MUL(GF_ADD(w0, GF_MUL(w1, x[1])), GF_INV(z[1])); if (n0 < ECC_PAYLOAD) mesg[n0] = GF_ADD(mesg[n0], e0); if (n1 < ECC_PAYLOAD) mesg[n1] = GF_ADD(mesg[n1], e1); return; case 3: z[3] = 1; z[2] = GF_MUL(syn[1], GF_MUL(syn[4], syn[6])); z[2] = GF_ADD(z[2], GF_MUL(syn[1], GF_MUL(syn[5], syn[5]))); z[2] = GF_ADD(z[2], GF_MUL(syn[5], GF_MUL(syn[3], syn[3]))); z[2] = GF_ADD(z[2], GF_MUL(syn[3], GF_MUL(syn[4], syn[4]))); z[2] = GF_ADD(z[2], GF_MUL(syn[2], GF_MUL(syn[5], syn[4]))); z[2] = GF_ADD(z[2], GF_MUL(syn[2], GF_MUL(syn[3], syn[6]))); z[2] = GF_MUL(z[2], GF_INV(deter)); z[1] = GF_MUL(syn[1], GF_MUL(syn[3], syn[6])); z[1] = GF_ADD(z[1], GF_MUL(syn[1], GF_MUL(syn[5], syn[4]))); z[1] = GF_ADD(z[1], GF_MUL(syn[4], GF_MUL(syn[3], syn[3]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[4], syn[4]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[3], syn[5]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[2], syn[6]))); z[1] = GF_MUL(z[1], GF_INV(deter)); z[0] = GF_MUL(syn[2], GF_MUL(syn[3], syn[4])); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[2], syn[4]))); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[5], syn[1]))); z[0] = GF_ADD(z[0], GF_MUL(syn[4], GF_MUL(syn[4], syn[1]))); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[3], syn[3]))); z[0] = GF_ADD(z[0], GF_MUL(syn[2], GF_MUL(syn[2], syn[5]))); z[0] = GF_MUL(z[0], GF_INV(deter)); polysolve (z, x, &sols); if (sols != 3) { *errcode = 4; return; } w0 = GF_MUL(z[0], syn[1]); w1 = GF_ADD(GF_MUL(z[0], syn[2]), GF_MUL(z[1], syn[1])); w2 = GF_ADD(GF_MUL(z[0], syn[3]), GF_ADD(GF_MUL(z[1], syn[2]), GF_MUL(z[2], syn[1]))); n0 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[0])]; n1 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[1])]; n2 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[2])]; e0 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[0]), GF_MUL(w2, GF_EXP(x[0], 2)))); e0 = GF_MUL(e0, GF_INV(GF_ADD(z[1], GF_EXP(x[0], 2)))); e1 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[1]), GF_MUL(w2, GF_EXP(x[1], 2)))); e1 = GF_MUL(e1, GF_INV(GF_ADD(z[1], GF_EXP(x[1], 2)))); e2 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[2]), GF_MUL(w2, GF_EXP(x[2], 2)))); e2 = GF_MUL(e2, GF_INV(GF_ADD(z[1], GF_EXP(x[2], 2)))); if (n0 < ECC_PAYLOAD) mesg[n0] = GF_ADD(mesg[n0], e0); if (n1 < ECC_PAYLOAD) mesg[n1] = GF_ADD(mesg[n1], e1); if (n2 < ECC_PAYLOAD) mesg[n2] = GF_ADD(mesg[n2], e2); return; } }