#include #include #include #include #define mm 8 /* RS code over GF(2**mm) - change to suit */ #define n 256 /* n = size of the field */ #define nn 182 /* nn=2**mm -1 length of codeword */ #define kk 172 /* kk = nn-2*tt */ /* Degree of g(x) = 2*tt */ //#define NN n-1 //#define FCR 0 //#define PRIM 1 #define _NROOTS nn-kk //#define PAD NN-nn //#define A0 NN //#define IPRIM 1 const int NN = n-1; const int FCR = 0; const int PRIM = 1; const int NROOTS = nn-kk; const int PAD = (n-1)-nn; const int A0 = n-1; const int IPRIM = 1; #ifndef min #define min(a,b) ((a) < (b) ? (a) : (b)) #endif /**** Primitive polynomial ****/ int pp [mm+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1}; /* 1+x^2+x^3+x^4+x^8 */ /* generator polynomial, tables for Galois field */ int alpha_to[n], index_of[n], gg[nn-kk+1]; int b0 = 1; /* data[] is the info vector, bb[] is the parity vector, recd[] is the noise corrupted received vector */ int recd[nn], data[kk], bb[nn-kk]; int modnn(int x){ while (x >= 0xff) { x -= 0xff; x = (x >> 0xff) + (x & 0xff); } return x; } void generate_gf() { register int i, mask ; mask = 1 ; alpha_to[mm] = 0 ; for (i=0; i>= 1 ; for (i=mm+1; i<255; i++) { if (alpha_to[i-1] >= mask) alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ; else alpha_to[i] = alpha_to[i-1]<<1 ; index_of[alpha_to[i]] = i ; } index_of[0] = A0 ;//-1 } void gen_poly() /* Obtain the generator polynomial of the tt-error correcting, length */ { register int i, j, root; gg[0] = 1; for (i = 0,root=0*1; i < nn-kk; i++,root += 1) { gg[i+1] = 1; for (j = i; j > 0; j--){ if (gg[j] != 0) gg[j] = gg[j-1] ^ alpha_to[modnn(index_of[gg[j]] + root)]; else gg[j] = gg[j-1]; } gg[0] = alpha_to[modnn(index_of[gg[0]] + root)]; } for (i=0; i <= nn-kk; i++) { gg[i] = index_of[gg[i]]; } } void rs_encode(unsigned char *data, unsigned char *bb) { register int i,j ; int feedback; for (i=0; i 0) { /* Init lambda to be the erasure locator polynomial */ lambda[1] = alpha_to[modnn(PRIM*(NN-1-eras_pos[0]))]; for (i = 1; i < no_eras; i++) { u = modnn(PRIM*(NN-1-eras_pos[i])); for (j = i+1; j > 0; j--) { tmp = index_of[lambda[j - 1]]; if(tmp != A0) lambda[j] ^= alpha_to[modnn(u + tmp)]; } } } for(i=0;i 0; j--){ if (reg[j] != A0) { reg[j] = modnn(reg[j] + j); q ^= alpha_to[reg[j]]; } } if (q != 0) continue; /* Not a root */ /* store root (index-form) and error location number */ root[count] = i; loc[count] = k; /* If we've already found max possible roots, * abort the search to save time */ if(++count == deg_lambda) break; } if (deg_lambda != count) { /* * deg(lambda) unequal to number of roots => uncorrectable * error detected */ count = -1; goto finish; } /* * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo * x**NROOTS). in index form. Also find deg(omega). */ deg_omega = deg_lambda-1; for (i = 0; i <= deg_omega;i++){ tmp = 0; for(j=i;j >= 0; j--){ if ((s[i - j] != A0) && (lambda[j] != A0)) tmp ^= alpha_to[modnn(s[i - j] + lambda[j])]; } omega[i] = index_of[tmp]; } /* * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = * inv(X(l))**(FCR-1) and den = lambda_pr(inv(X(l))) all in poly-form */ for (j = count-1; j >=0; j--) { num1 = 0; for (i = deg_omega; i >= 0; i--) { if (omega[i] != A0) num1 ^= alpha_to[modnn(omega[i] + i * root[j])]; } num2 = alpha_to[modnn(root[j] * (FCR - 1) + NN)]; den = 0; /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ for (i = min(deg_lambda,NROOTS-1) & ~1; i >= 0; i -=2) { if(lambda[i+1] != A0) den ^= alpha_to[modnn(lambda[i+1] + i * root[j])]; } /* Apply error to data */ if (num1 != 0 && loc[j] >= PAD) { data[loc[j]-PAD] ^= alpha_to[modnn(index_of[num1] + index_of[num2] + NN - index_of[den])]; } } finish: if(eras_pos != NULL){ for(i=0;i