public GF256Poly[] divide(GF256Poly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GF256Polys do not have same GF256 field"); } if (other.isZero()) { throw new ArgumentException("Divide by 0"); } GF256Poly quotient = field.getZero(); GF256Poly remainder = this; int denominatorLeadingTerm = other.getCoefficient(other.getDegree()); int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm); while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) { int degreeDifference = remainder.getDegree() - other.getDegree(); int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm); GF256Poly term = other.multiplyByMonomial(degreeDifference, scale); GF256Poly iterationQuotient = field.buildMonomial(degreeDifference, scale); quotient = quotient.addOrSubtract(iterationQuotient); remainder = remainder.addOrSubtract(term); } return(new GF256Poly[] { quotient, remainder }); }
/** * <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> * * @param received data and error-correction codewords * @param twoS number of error-correction codewords available * @throws ReedSolomonException if decoding fails for any reason */ public void decode(int[] received, int twoS) { try{ 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]); } }catch (ReedSolomonException e) { throw new ReedSolomonException(e.Message); } }