private GF256Poly buildGenerator(int degree) { if (degree >= cachedGenerators.Count) { GF256Poly lastGenerator = (GF256Poly)cachedGenerators[cachedGenerators.Count - 1]; for (int d = cachedGenerators.Count; d <= degree; d++) { GF256Poly nextGenerator = lastGenerator.multiply(new GF256Poly(field, new int[] { 1, field.exp(d - 1) })); cachedGenerators.Add(nextGenerator); lastGenerator = nextGenerator; } } return((GF256Poly)cachedGenerators[degree]); }
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"); } }
private GF256Poly[] runEuclideanAlgorithm(GF256Poly a, GF256Poly b, int R) { // Assume a's degree is >= b's if (a.Degree < b.Degree) { GF256Poly temp = a; a = b; b = temp; } GF256Poly rLast = a; GF256Poly r = b; GF256Poly sLast = field.One; GF256Poly s = field.Zero; GF256Poly tLast = field.Zero; GF256Poly t = field.One; // Run Euclidean algorithm until r's degree is less than R/2 while (r.Degree >= R / 2) { GF256Poly rLastLast = rLast; GF256Poly sLastLast = sLast; GF256Poly tLastLast = tLast; rLast = r; sLast = s; tLast = t; // Divide rLastLast by rLast, with quotient in q and remainder in r if (rLast.Zero) { // Oops, Euclidean algorithm already terminated? throw new ReedSolomonException("r_{i-1} was zero"); } r = rLastLast; GF256Poly q = field.Zero; int denominatorLeadingTerm = rLast.getCoefficient(rLast.Degree); int dltInverse = field.inverse(denominatorLeadingTerm); while (r.Degree >= rLast.Degree && !r.Zero) { int degreeDiff = r.Degree - rLast.Degree; int scale = field.multiply(r.getCoefficient(r.Degree), dltInverse); q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale)); } s = q.multiply(sLast).addOrSubtract(sLastLast); t = q.multiply(tLast).addOrSubtract(tLastLast); } int sigmaTildeAtZero = t.getCoefficient(0); if (sigmaTildeAtZero == 0) { throw new ReedSolomonException("sigmaTilde(0) was zero"); } int inverse = field.inverse(sigmaTildeAtZero); GF256Poly sigma = t.multiply(inverse); GF256Poly omega = r.multiply(inverse); return(new GF256Poly[] { sigma, omega }); }