📄 maxicode.c
字号:
/* data[len+j] = base_reg[j]; */ tint = base_reg[EClen-1-j]; // put_back(tint); ecc_results[j] = tint; } } void coeff_init_32() { mods_10[0] = 1; mods_10[1] = 31; mods_10[2] = 28; mods_10[3] = 39; mods_10[4] = 42; mods_10[5] = 57; mods_10[6] = 2; mods_10[7] = 3; mods_10[8] = 49; mods_10[9] = 44; mods_10[10] = 46; mods_20[0] = 1; mods_20[1] = 23; mods_20[2] = 44; mods_20[3] = 11; mods_20[4] = 33; mods_20[5] = 27; mods_20[6] = 8; mods_20[7] = 22; mods_20[8] = 37; mods_20[9] = 57; mods_20[10] = 36; mods_20[11] = 15; mods_20[12] = 48; mods_20[13] = 22; mods_20[14] = 17; mods_20[15] = 38; mods_20[16] = 33; mods_20[17] = 31; mods_20[18] = 19; mods_20[19] = 23; mods_20[20] = 59; mods_28[0] = 1; mods_28[1] = 22; mods_28[2] = 45; mods_28[3] = 53; mods_28[4] = 10; mods_28[5] = 41; mods_28[6] = 55; mods_28[7] = 35; mods_28[8] = 10; mods_28[9] = 22; mods_28[10] = 29; mods_28[11] = 23; mods_28[12] = 13; mods_28[13] = 61; mods_28[14] = 45; mods_28[15] = 34; mods_28[16] = 55; mods_28[17] = 40; mods_28[18] = 37; mods_28[19] = 46; mods_28[20] = 49; mods_28[21] = 34; mods_28[22] = 41; mods_28[23] = 9; mods_28[24] = 43; mods_28[25] = 7; mods_28[26] = 20; mods_28[27] = 11; mods_28[28] = 28; } /* end */int modbase(int x){ return ( x % (GPRIME -1 ));}int modnn(int x){ while (x >= NN) { x -= NN; x = (x >> MM) + (x & NN); } return x;}void generate_gf(void){ register int i, mask; int debug; mask = 1; Alpha_to[MM] = 0; for (i = 0; i < MM; i++) { Alpha_to[i] = mask; Index_of[Alpha_to[i]] = i; /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */ if (Pp[i] != 0) Alpha_to[MM] ^= mask; /* Bit-wise EXOR operation */ mask <<= 1; /* single left-shift */ } Index_of[Alpha_to[MM]] = MM; /* * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by * poly-repr of @^i shifted left one-bit and accounting for any @^MM * term that may occur when poly-repr of @^i is shifted. */ mask >>= 1; for (i = MM + 1; i < NN; 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; Alpha_to[NN] = 0; if (debug) { for(i = 0; i < 64; i += 1) { printf("Alpha_to[%d] = %d \n", i, Alpha_to[i]); } for(i = 0; i < 64; i += 1) { printf("Index_of[%d] = %d \n", i, Index_of[i]); } }}/* * Obtain the generator polynomial of the TT-error correcting, length * NN=(2**MM -1) Reed Solomon code from the product of (X+@**(B0+i)), i = 0, * ... ,(2*TT-1) * * Examples: * * If B0 = 1, TT = 1. deg(g(x)) = 2*TT = 2. * g(x) = (x+@) (x+@**2) * * If B0 = 0, TT = 2. deg(g(x)) = 2*TT = 4. * g(x) = (x+1) (x+@) (x+@**2) (x+@**3) */static voidgen_poly(void){ register int i, j; Gg[0] = 1; for (i = 0; i < NN - KK; i++) { Gg[i+1] = 1; /* * Below multiply (Gg[0]+Gg[1]*x + ... +Gg[i]x^i) by * (@**(B0+i)*PRIM + x) */ for (j = i; j > 0; j--) if (Gg[j] != 0) Gg[j] = Gg[j - 1] ^ Alpha_to[modnn((Index_of[Gg[j]]) + (B0 + i) *PRIM)]; else Gg[j] = Gg[j - 1]; /* Gg[0] can never be zero */ Gg[0] = Alpha_to[modnn(Index_of[Gg[0]] + (B0 + i) * PRIM)]; } /* convert Gg[] to index form for quicker encoding */ for (i = 0; i <= NN - KK; i++) Gg[i] = Index_of[Gg[i]];}void init_rs(){ generate_gf(); gen_poly(); RS_init = 1;} /* * take the string of symbols in data[i], i=0..(k-1) and encode * systematically to produce NN-KK parity symbols in bb[0]..bb[NN-KK-1] data[] * is input and bb[] is output in polynomial form. Encoding is done by using * a feedback shift register with appropriate connections specified by the * elements of Gg[], which was generated above. Codeword is c(X) = * data(X)*X**(NN-KK)+ b(X) */intencode_rs(int data[KK], int bb[NN-KK]){ register int i, j; int feedback; /* Check for illegal input values */ for(i=0;i<KK;i++) if(data[i] > NN) return -1; // if(!RS_init) // init_rs(); CLEAR(bb,NN-KK); for(i = KK - 1; i >= 0; i--) { feedback = Index_of[data[i] ^ bb[NN - KK - 1]]; if (feedback != A0) { /* feedback term is non-zero */ for (j = NN - KK - 1; j > 0; j--) if (Gg[j] != A0) bb[j] = bb[j - 1] ^ Alpha_to[modnn(Gg[j] + feedback)]; else bb[j] = bb[j - 1]; bb[0] = Alpha_to[modnn(Gg[0] + feedback)]; } else { /* feedback term is zero. encoder becomes a * single-byte shifter */ for (j = NN - KK - 1; j > 0; j--) bb[j] = bb[j - 1]; bb[0] = 0; } } return 0;} /* * Performs ERRORS+ERASURES decoding of RS codes. If decoding is successful, * writes the codeword into data[] itself. Otherwise data[] is unaltered. * * Return number of symbols corrected, or -1 if codeword is illegal * or uncorrectable. If eras_pos is non-null, the detected error locations * are written back. NOTE! This array must be at least NN-KK elements long. * * First "no_eras" erasures are declared by the calling program. Then, the * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2). * If the number of channel errors is not greater than "t_after_eras" the * transmitted codeword will be recovered. Details of algorithm can be found * in R. Blahut's "Theory ... of Error-Correcting Codes". * Warning: the eras_pos[] array must not contain duplicate entries; decoder failure * will result. The decoder *could* check for this condition, but it would involve * extra time on every decoding operation. */interas_dec_rs(int data[NN], int eras_pos[NN-KK], int no_eras, int data_len, int synd_len){ int deg_lambda, el, deg_omega; int i, j, r,k; int u,q,tmp,num1,num2,den,discr_r; int lambda[512 + 1], s[512 + 1]; /* Err+Eras Locator poly * and syndrome poly */ int b[512 + 1], t[512 + 1], omega[512 + 1]; int root[512], reg[512 + 1], loc[512]; int syn_error, count; int fix_loc; int error_val; int mismatch; int debug; int ci; int ato; if(!RS_init) init_rs(); debug = 0; if (set_debug) { debug =1 ; } /* Check for illegal input values */ for(i=0;i< data_len;i++) if(data[i] > GPRIME) return -1; /* form the syndromes; i.e., evaluate data(x) at roots of g(x) * namely @**(B0+i)*PRIM, i = 0, ... ,(NN-KK-1) */ for(i=1;i<=synd_len;i++){ s[i] = data[data_len-1]; } if (debug) { printf("data[data_len-1] = %d I_of same = %d \n", data[data_len-1] , Index_of[data[data_len-1]]); } for(j=1;j<data_len;j++){ if(data[data_len-1-j] == 0) continue; tmp = Index_of[data[data_len-1-j]]; if (debug) { printf("Data[%d] = %d tmp = %d \n", data_len-j-1, data[data_len-j-1], tmp); } /* s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*j)]; */ for(i=1;i<=synd_len;i++) { ato = Alpha_to[modnn(tmp+(i*j))]; if ( debug) { printf("pre s[%d] = %d \n", i, s[i]); } s[i] = (s[i] ^ Alpha_to[modnn(tmp + (i*j))]) ; if (debug) { printf("s[%d] = %d \n",i,s[i]); } if (debug) { printf("modnn = %d \n",modnn(tmp + (i*j))); } if (debug) { printf(" i = %d j = %d tmp = %d \n",i,j,tmp); } if (debug) { printf("ato = %d \n",ato); } } } mismatch = FALSE; for ( j= 0; j < synd_len ; j += 1) { if ( s[j + 1] != synd_array[j]) { if (debug) { printf("Syndrome mismatch j = %d s[j] = %d I_of s[j] = %d synd_array[j] = %d \n", j, s[j+1],Index_of[s[j+1]], synd_array[j]); mismatch = TRUE; } } } if ( mismatch == FALSE) { if (debug) { printf("Correct syndromes \n"); } } else { printf("Syndrome mismatch \n"); } /* Convert syndromes to index form, checking for nonzero condition */ syn_error = 0; for(i=1;i<=synd_len;i++){ syn_error |= s[i]; s[i] = Index_of[s[i]]; } if (!syn_error) { /* if syndrome is zero, data[] is a codeword and there are no * errors to correct. So return data[] unmodified */ count = 0; goto finish; } // CLEAR(&lambda[1],NN-KK); for(ci=synd_len-1;ci >=0;ci--) lambda[ci+1] = 0; lambda[0] = 1; if (no_eras > 0) { /* Init lambda to be the erasure locator polynomial */ lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])]; for (i = 1; i < no_eras; i++) { u = modnn(PRIM*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)]; } }#if DEBUG >= 1 /* Test code that verifies the erasure locator polynomial just constructed Needed only for decoder debugging. */ /* find roots of the erasure location polynomial */ for(i=1;i<=no_eras;i++) reg[i] = Index_of[lambda[i]]; count = 0; for (i = 1,k=data_len-Ldec; i <= data_len + synd_len ; i++,k = modnn(data_len+k-Ldec)) { q = 1; for (j = 1; j <= no_eras; j++) if (reg[j] != A0) { reg[j] = modnn(reg[j] + j); q ^= Alpha_to[reg[j]]; } if (q != 0) continue; /* store root and error location number indices */ root[count] = i; loc[count] = k; count++; } if (count != no_eras) { printf("\n lambda(x) is WRONG\n"); count = -1; goto finish; }#if DEBUG >= 2 printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); for (i = 0; i < count; i++) printf("%d ", loc[i]); printf("\n");#endif#endif } for(i=0;i<synd_len+1;i++) b[i] = Index_of[lambda[i]]; /* * Begin Berlekamp-Massey algorithm to determine error+erasure * locator polynomial */ r = no_eras; el = no_eras; if (debug) { printf("no_eras = %d \n",no_eras); } while (++r <= synd_len) { /* r is the step number */ /* Compute discrepancy at the r-th step in poly-form */ discr_r = 0; for (i = 0; i < r; i++){ if ((lambda[i] != 0) && (s[r - i] != A0)) { discr_r ^= Alpha_to[modnn(Index_of[lambda[i]] + s[r - i])]; if (debug) { printf("discr_r = %d i = %d r = %d lambda[i] = %d s[r-i] = %d \n", discr_r, i, r, lambda[i], s[r-i] ); } } } discr_r = Index_of[discr_r]; /* Index form */ if (debug) { printf("I_of[discr_r] = %d \n", discr_r); } if (discr_r == A0) { /* 2 lines below: B(x) <-- x*B(x) */ // COPYDOWN(&b[1],b,NN-KK); for(ci=synd_len-1;ci >=0;ci--) { b[ci+1] = b[ci]; } b[0] = A0; } else { /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */ t[0] = lambda[0]; for (i = 0 ; i < synd_len; i++) { if(b[i] != A0) t[i+1] = lambda[i+1] ^ Alpha_to[modnn(discr_r + b[i])]; else t[i+1] = lambda[i+1]; } if (2 * el <= r + no_eras - 1) { el = r + no_eras - el; /* * 2 lines below: B(x) <-- inv(discr_r) * * lambda(x) */ for (i = 0; i <= synd_len; i++) b[i]=(lambda[i]==0) ? A0 : modnn(Index_of[lambda[i]] - discr_r + NN); } else { /* 2 lines below: B(x) <-- x*B(x) */ // COPYDOWN(&b[1],b,NN-KK); for(ci=synd_len-1;ci >=0;ci--) { b[ci+1] = b[ci]; } b[0] = A0; } // COPY(lambda,t,NN-KK+1); for(ci=synd_len;ci >=0;ci--) { lambda[ci] = t[ci]; if (debug) { printf("ci = %d Lambda = %d i_of Lambda = %d \n", ci, t[ci], Index_of[t[ci]]); } } } } /* Convert lambda to index form and compute deg(lambda(x)) */ deg_lambda = 0; for(i=0;i<synd_len+1;i++){ lambda[i] = Index_of[lambda[i]]; if(lambda[i] != A0) deg_lambda = i; } /* * Find roots of the error+erasure locator polynomial by Chien * Search */ // COPY(®[1],&lambda[1],NN-KK); for(ci=synd_len-1;ci >=0;ci--) reg[ci+1] = lambda[ci+1]; count = 0; /* Number of roots of lambda(x) */ for (i = 1; i <= NN+1; i++) { q = 1; for (j = deg_lambda; j > 0; j--){ if (debug) { printf(" Reg[j] = %d q = %d i = %d j=%d\n", reg[j], q, i, j ); } if (reg[j] != A0) { reg[j] = modnn(reg[j] + j); q ^= Alpha_to[reg[j]]; } } if (debug) { printf(" q after = %d i = %d\n", q, i ); } if (q != 0) continue; /* store root (index-form) and error location number */ root[count] = i; loc[count] = NN + 1 - i; /* 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**(NN-KK)). in index form. Also find deg(omega). */ deg_omega = 0; for (i = 0; i < synd_len;i++){ tmp = 0; j = (deg_lambda < i) ? deg_lambda : i; for(;j >= 0; j--){ if ((s[i + 1 - j] != A0) && (lambda[j] != A0)) tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])]; } if(tmp != 0) deg_omega = i; omega[i] = Index_of[tmp]; } omega[synd_len] = A0; /* * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = * inv(X(l))**(B0-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] * (B0 - 1) + NN)]; num2 = 1; den = 0; // denominator if product of all (1 - Bj Bk) for k != j // if count = 1, then den = 1 // alternate way to find denominator... // den = 1; // for ( k = 0; k < count ; k += 1) // { // if ( k != j) // { // tmp = modnn( 0xff ^ Alpha_to[modnn(root[k] + root[j])]); // // den = Alpha_to[ modnn( Index_of[den] + Index_of[tmp])]; // } // } /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ for (i = min(deg_lambda,synd_len-1) & ~1; i >= 0; i -=2) { if(lambda[i+1] != A0) den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -