void RSCoder::Encode(unsigned char *Data,int DataSize,unsigned char *DestData) { int ShiftReg[MAXPAR+1]; Clean(ShiftReg,ParSize+1); for (int I=0;I<DataSize;I++) { int D=Data[I]^ShiftReg[ParSize-1]; for (int J=ParSize-1;J>0;J--) ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D); ShiftReg[0]=gfMult(GXPol[0],D); } for (int I=0;I<ParSize;I++) DestData[I]=ShiftReg[ParSize-I-1]; }
void RSCoder::Encode(byte *Data,int DataSize,byte *DestData) { int ShiftReg[MAXPAR+1]; // Linear Feedback Shift Register. Clean(ShiftReg,ParSize+1); for (int I=0;I<DataSize;I++) { int D=Data[I]^ShiftReg[ParSize-1]; // Use g(x) to define feedback taps. for (int J=ParSize-1;J>0;J--) ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D); ShiftReg[0]=gfMult(GXPol[0],D); } for (int I=0;I<ParSize;I++) DestData[I]=ShiftReg[ParSize-I-1]; }
// Multiply polynomial 'p1' to 'p2' and store the result in 'r'. void RSCoder::pnMult(int *p1,int *p2,int *r) { Clean(r,ParSize); for (int I=0;I<ParSize;I++) if (p1[I]!=0) for(int J=0;J<ParSize-I;J++) r[I+J]^=gfMult(p1[I],p2[J]); }
/* return a u32 containing the result of multiplying the RS Code matrix by the sd matrix */ u32 RSMatrixMultiply(BYTE sd[8]) { int j, k; BYTE t; BYTE result[4]; for (j = 0; j < 4; j++) { t = 0; for (k = 0; k < 8; k++) { /*printf("t=%X %X\n", t, gfMult(RS[j][k], sd[k], RS_MOD));*/ t ^= gfMult(RS[j][k], sd[k], RS_MOD); } result[3-j] = t; } return BYTEARRAY_TO_U32(result); }
bool RSCoder::Decode(byte *Data,int DataSize,int *EraLoc,int EraSize) { int SynData[MAXPOL]; // Syndrome data. bool AllZeroes=true; for (int I=0;I<ParSize;I++) { int Sum=0; for (int J=0;J<DataSize;J++) Sum=Data[J]^gfMult(gfExp[I+1],Sum); if ((SynData[I]=Sum)!=0) AllZeroes=false; } // If all syndrome numbers are zero, message does not have errors. if (AllZeroes) return(true); if (!FirstBlockDone) // Do things which we need to do once for all data. { FirstBlockDone=true; // Calculate the error locator polynomial. Clean(ELPol,ParSize+1); ELPol[0]=1; for (int EraPos=0;EraPos<EraSize;EraPos++) for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--) ELPol[I]^=gfMult(M,ELPol[I-1]); ErrCount=0; // Find roots of error locator polynomial. for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++) { int Sum=0; for (int B=0;B<ParSize+1;B++) Sum^=gfMult(gfExp[(B*Root)%MAXPAR],ELPol[B]); if (Sum==0) // Root found. { ErrorLocs[ErrCount]=MAXPAR-Root; // Location of error. // Calculate the denominator for every error location. Dnm[ErrCount]=0; for (int I=1;I<ParSize+1;I+=2) Dnm[ErrCount]^= gfMult(ELPol[I],gfExp[Root*(I-1)%MAXPAR]); ErrCount++; } } } int EEPol[MAXPOL]; // Error Evaluator Polynomial. pnMult(ELPol,SynData,EEPol); // If errors are present and their number is correctable. if ((ErrCount<=ParSize) && ErrCount>0) for (int I=0;I<ErrCount;I++) { int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0; for (int J=0;J<ParSize;J++) N^=gfMult(EEPol[J],gfExp[DLoc*J%MAXPAR]); int DataPos=DataSize-Loc-1; // Perform bounds check and correct the data error. if (DataPos>=0 && DataPos<DataSize) Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dnm[I]]]); } return(ErrCount<=ParSize); // Return true if success. }
bool RSCoder::Decode(unsigned char *Data,int DataSize,int *EraLoc,int EraSize) { int SynData[MAXPOL]; bool AllZeroes=true; for (int I=0;I<ParSize;I++) { int Sum=Data[0],J=1,Exp=gfExp[I+1]; for (;J+8<=DataSize;J+=8) { Sum=Data[J]^gfMult(Exp,Sum); Sum=Data[J+1]^gfMult(Exp,Sum); Sum=Data[J+2]^gfMult(Exp,Sum); Sum=Data[J+3]^gfMult(Exp,Sum); Sum=Data[J+4]^gfMult(Exp,Sum); Sum=Data[J+5]^gfMult(Exp,Sum); Sum=Data[J+6]^gfMult(Exp,Sum); Sum=Data[J+7]^gfMult(Exp,Sum); } for (;J<DataSize;J++) Sum=Data[J]^gfMult(Exp,Sum); if ((SynData[I]=Sum)!=0) AllZeroes=false; } if (AllZeroes) return(true); if (!FirstBlockDone) { FirstBlockDone=true; Clean(PolB,ParSize+1); PolB[0]=1; for (int EraPos=0;EraPos<EraSize;EraPos++) for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--) PolB[I]^=gfMult(M,PolB[I-1]); ErrCount=0; for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++) { int Sum=0; for (int B=0;B<ParSize+1;B++) Sum^=gfMult(gfExp[(B*Root)%MAXPAR],PolB[B]); if (Sum==0) { Dn[ErrCount]=0; for (int I=1;I<ParSize+1;I+=2) Dn[ErrCount]^= gfMult(PolB[I],gfExp[Root*(I-1)%MAXPAR]); ErrorLocs[ErrCount++]=MAXPAR-Root; } } } int PolD[MAXPOL]; pnMult(PolB,SynData,PolD); if ((ErrCount<=ParSize) && ErrCount>0) for (int I=0;I<ErrCount;I++) { int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0; for (int J=0;J<ParSize;J++) N^=gfMult(PolD[J],gfExp[DLoc*J%MAXPAR]); int DataPos=DataSize-Loc-1; if (DataPos>=0 && DataPos<DataSize) Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dn[I]]]); } return(ErrCount<=ParSize); }