// 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);
    
}
Beispiel #2
0
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]);
    }
  }
Beispiel #5
0
/*
 * 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;
	}
}