private void TestOneCase(int[] aCoeff, int[] bCoeff, string option, int[] expect) { GaloisField256 gfield = GaloisField256.QRCodeGaloisField; Polynomial apoly = new Polynomial(gfield, aCoeff); Polynomial bpoly = new Polynomial(gfield, bCoeff); int[] result = resultCoeff(apoly, bpoly, option); if(!PolynomialExtensions.isEqual(result, expect)) Assert.Fail("result {0} expect {1} option {2}", result[0], expect[0], option); }
private int[] resultCoeff(Polynomial apoly, Polynomial bpoly, string option) { switch(option) { case "xor": return apoly.AddOrSubtract(bpoly).Coefficients; case "multy": return apoly.Multiply(bpoly).Coefficients; default: throw new ArgumentException("No such math option for polynomial"); } }
private void TestOneCase(int[] aCoeff, int[] bCoeff, int[] expQuotient, int[] expRemainder) { GaloisField256 gfield = GaloisField256.QRCodeGaloisField; Polynomial apoly = new Polynomial(gfield, aCoeff); Polynomial bpoly = new Polynomial(gfield, bCoeff); PolyDivideStruct pds = apoly.Divide(bpoly); int[] quotient = pds.Quotient.Coefficients; int[] remainder = pds.Remainder.Coefficients; if(!PolynomialExtensions.isEqual(quotient, expQuotient)) Assert.Fail("Quotient not equal. Result {0}, Expect {1}", aCoeff.Length, bCoeff.Length); if(!PolynomialExtensions.isEqual(remainder, expRemainder)) Assert.Fail("Remainder not equal. Result {0}, Expect {1}", remainder.Length, aCoeff.Length); }
/// <summary> /// Encode an array of data codeword with GaloisField 256. /// </summary> /// <param name="dataBytes">Array of data codewords for a single block.</param> /// <param name="numECBytes">Number of error correction codewords for data codewords</param> /// <param name="generatorPoly">Cached or newly create GeneratorPolynomial</param> /// <returns>Return error correction codewords array</returns> internal static byte[] Encode(byte[] dataBytes, int numECBytes, GeneratorPolynomial generatorPoly) { int dataLength = dataBytes.Length; if(generatorPoly == null) throw new ArgumentNullException("generator", "GeneratorPolynomial var is null"); if(dataLength == 0) throw new ArgumentException("There is no data bytes to encode"); if(numECBytes <= 0) throw new ArgumentException("No Error Correction bytes"); int[] toEncode = ConvertToIntArray(dataBytes, dataLength, numECBytes); Polynomial generator = generatorPoly.GetGenerator(numECBytes); Polynomial dataPoly = new Polynomial(generator.GField, toEncode); PolyDivideStruct divideResult = dataPoly.Divide(generator); int[] remainderCoeffs = divideResult.Remainder.Coefficients; return ConvertTosByteArray(remainderCoeffs, numECBytes); }
internal PolyDivideStruct(Polynomial quotient, Polynomial remainder) : this() { this.Quotient = quotient; this.Remainder = remainder; }
/// <summary> /// Multiply current Polynomial to anotherone. /// </summary> /// <returns>Result polynomial after multiply</returns> internal Polynomial Multiply(Polynomial other) { if(this.Primitive != other.Primitive) { throw new ArgumentException("Polynomial can not perform Multiply as they don't have same Primitive for GaloisField256"); } if(this.isMonomialZero || other.isMonomialZero) return new Polynomial(this.GField, new int[]{0}); int[] aCoefficients = this.Coefficients; int aLength = aCoefficients.Length; int[] bCoefficient = other.Coefficients; int bLength = bCoefficient.Length; int[] rCoefficients = new int[aLength + bLength - 1]; for(int aIndex = 0; aIndex < aLength; aIndex++) { int aCoeff = aCoefficients[aIndex]; for(int bIndex = 0; bIndex < bLength; bIndex++) { rCoefficients[aIndex + bIndex] = this.GField.Addition(rCoefficients[aIndex + bIndex], this.GField.Product(aCoeff, bCoefficient[bIndex])); } } return new Polynomial(this.GField, rCoefficients); }
/// <summary> /// divide current polynomial by "other" /// </summary> /// <returns>Result polynomial after divide</returns> internal PolyDivideStruct Divide(Polynomial other) { if(this.Primitive != other.Primitive) { throw new ArgumentException("Polynomial can not perform Devide as they don't have same Primitive for GaloisField256"); } if(other.isMonomialZero) { throw new ArgumentException("Can not devide by Polynomial Zero"); } //this devide by other = a devide by b int aLength = this.Coefficients.Length; //We will make change to aCoefficient. It will return as remainder int[] aCoefficients = new int[aLength]; Array.Copy(this.Coefficients, 0, aCoefficients, 0, aLength); int bLength = other.Coefficients.Length; if(aLength < bLength) return new PolyDivideStruct(new Polynomial(this.GField, new int[]{0}), this); else { //quotient coefficients //qLastIndex = alength - blength qlength = qLastIndex + 1 int[] qCoefficients = new int[( aLength - bLength ) + 1]; //Denominator int otherLeadingTerm = other.GetCoefficient(other.Degree); int inverseOtherLeadingTerm = this.GField.inverse(otherLeadingTerm); for(int aIndex = 0; aIndex <= aLength - bLength; aIndex++) { if(aCoefficients[aIndex] != 0) { int aScalar = this.GField.Product(inverseOtherLeadingTerm, aCoefficients[aIndex]); Polynomial term = other.MultiplyScalar(aScalar); qCoefficients[aIndex] = aScalar; int[] bCoefficient = term.Coefficients; if(bCoefficient[0] != 0) { for(int bIndex = 0; bIndex < bLength; bIndex++) { aCoefficients[aIndex + bIndex] = this.GField.Subtraction(aCoefficients[aIndex + bIndex], bCoefficient[bIndex]); } } } } return new PolyDivideStruct(new Polynomial(this.GField, qCoefficients), new Polynomial(this.GField, aCoefficients)); } }
/// <summary> /// Add another Polynomial to current one /// </summary> /// <param name="other">The polynomial need to add or subtract to current one</param> /// <returns>Result polynomial after add or subtract</returns> internal Polynomial AddOrSubtract(Polynomial other) { if(this.Primitive != other.Primitive) { throw new ArgumentException("Polynomial can not perform AddOrSubtract as they don't have same Primitive for GaloisField256"); } if(this.isMonomialZero) return other; else if(other.isMonomialZero) return this; int otherLength = other.Coefficients.Length; int thisLength = this.Coefficients.Length; if(otherLength > thisLength) return CoefficientXor(this.Coefficients, other.Coefficients); else return CoefficientXor(other.Coefficients, this.Coefficients); }