private int[] findErrorMagnitudes(GF256Poly errorEvaluator, int[] errorLocations, bool dataMatrix) { // This is directly applying Forney's Formula int s = errorLocations.Length; int[] result = new int[s]; for (int i = 0; i < s; i++) { int xiInverse = field.inverse(errorLocations[i]); int denominator = 1; for (int j = 0; j < s; j++) { if (i != j) { denominator = field.multiply(denominator, GF256.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); } } result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator)); // Thanks to sanfordsquires for this fix: if (dataMatrix) { result[i] = field.multiply(result[i], xiInverse); } } return(result); }
private int[] MathForReferenceImplementation(int[] aCoeff, int[] bCoeff, string option) { GF256 field = GF256.QR_CODE_FIELD; GF256Poly aPoly = new GF256Poly(field, aCoeff); GF256Poly bPoly = new GF256Poly(field, bCoeff); switch (option) { case "xor": return(aPoly.addOrSubtract(bPoly).Coefficients); case "multy": return(aPoly.multiply(bPoly).Coefficients); default: throw new ArgumentException("No such test option"); } }
/// <summary> <p>Decodes given set of received codewords, which include both data and error-correction /// codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place, /// in the input.</p> /// /// </summary> /// <param name="received">data and error-correction codewords /// </param> /// <param name="twoS">number of error-correction codewords available /// </param> /// <throws> ReedSolomonException if decoding fails for any reason </throws> public void decode(int[] received, int twoS) { GF256Poly poly = new GF256Poly(field, received); int[] syndromeCoefficients = new int[twoS]; bool dataMatrix = field.Equals(GF256.DATA_MATRIX_FIELD); bool noError = true; for (int i = 0; i < twoS; i++) { // Thanks to sanfordsquires for this fix: int eval = poly.evaluateAt(field.exp(dataMatrix?i + 1:i)); syndromeCoefficients[syndromeCoefficients.Length - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return; } GF256Poly syndrome = new GF256Poly(field, syndromeCoefficients); GF256Poly[] sigmaOmega = runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS); GF256Poly sigma = sigmaOmega[0]; GF256Poly omega = sigmaOmega[1]; int[] errorLocations = findErrorLocations(sigma); int[] errorMagnitudes = findErrorMagnitudes(omega, errorLocations, dataMatrix); for (int i = 0; i < errorLocations.Length; i++) { int position = received.Length - 1 - field.log(errorLocations[i]); if (position < 0) { throw new ReedSolomonException("Bad error location"); } received[position] = GF256.addOrSubtract(received[position], errorMagnitudes[i]); } }
public ReedSolomonDecoder(GF256 field) { this.field = field; }