/// <param name="field"> /// the /// <see cref="GF256"/> /// instance representing the field to use /// to perform computations /// </param> /// <param name="coefficients"> /// coefficients as ints representing elements of GF(256), arranged /// from most significant (highest-power term) coefficient to least significant /// </param> internal GF256Poly(GF256 field, int[] coefficients) { if (coefficients == null || coefficients.Length == 0) { throw new ArgumentException(); } this.field = field; int coefficientsLength = coefficients.Length; if (coefficientsLength > 1 && coefficients[0] == 0) { // Leading term must be non-zero for anything except the constant polynomial "0" int firstNonZero = 1; while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) { firstNonZero++; } if (firstNonZero == coefficientsLength) { this.coefficients = field.GetZero().coefficients; } else { this.coefficients = new int[coefficientsLength - firstNonZero]; Array.Copy(coefficients, firstNonZero, this.coefficients, 0, this.coefficients.Length); } } else { this.coefficients = coefficients; } }
/// <summary>GF multiplication</summary> /// <param name="other">the other GF-poly</param> /// <returns>new GF-poly obtained by multiplying this with other</returns> internal iText.Barcodes.Qrcode.GF256Poly Multiply(iText.Barcodes.Qrcode.GF256Poly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GF256Polys do not have same GF256 field"); } if (IsZero() || other.IsZero()) { return(field.GetZero()); } int[] aCoefficients = this.coefficients; int aLength = aCoefficients.Length; int[] bCoefficients = other.coefficients; int bLength = bCoefficients.Length; int[] product = new int[aLength + bLength - 1]; for (int i = 0; i < aLength; i++) { int aCoeff = aCoefficients[i]; for (int j = 0; j < bLength; j++) { product[i + j] = GF256.AddOrSubtract(product[i + j], field.Multiply(aCoeff, bCoefficients[j])); } } return(new iText.Barcodes.Qrcode.GF256Poly(field, product)); }
/// <returns>evaluation of this polynomial at a given point</returns> internal int EvaluateAt(int a) { if (a == 0) { // Just return the x^0 coefficient return(GetCoefficient(0)); } int size = coefficients.Length; if (a == 1) { // Just the sum of the coefficients int result = 0; for (int i = 0; i < size; i++) { result = GF256.AddOrSubtract(result, coefficients[i]); } return(result); } int result_1 = coefficients[0]; for (int i = 1; i < size; i++) { result_1 = GF256.AddOrSubtract(field.Multiply(a, result_1), coefficients[i]); } return(result_1); }
/// <summary>GF addition or subtraction (they are identical for a GF(2^n)</summary> /// <param name="other">the other GF-poly</param> /// <returns>new GF256Poly obtained by summing this GF and other</returns> internal iText.Barcodes.Qrcode.GF256Poly AddOrSubtract(iText.Barcodes.Qrcode.GF256Poly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GF256Polys do not have same GF256 field"); } if (IsZero()) { return(other); } if (other.IsZero()) { return(this); } int[] smallerCoefficients = this.coefficients; int[] largerCoefficients = other.coefficients; if (smallerCoefficients.Length > largerCoefficients.Length) { int[] temp = smallerCoefficients; smallerCoefficients = largerCoefficients; largerCoefficients = temp; } int[] sumDiff = new int[largerCoefficients.Length]; int lengthDiff = largerCoefficients.Length - smallerCoefficients.Length; // Copy high-order terms only found in higher-degree polynomial's coefficients Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff); for (int i = lengthDiff; i < largerCoefficients.Length; i++) { sumDiff[i] = GF256.AddOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return(new iText.Barcodes.Qrcode.GF256Poly(field, sumDiff)); }
/// <summary> /// Creates a SolomonEncoder object based on a /// <see cref="GF256"/> /// object. /// </summary> /// <remarks> /// Creates a SolomonEncoder object based on a /// <see cref="GF256"/> /// object. /// Only QR codes are supported at the moment. /// </remarks> /// <param name="field">the galois field</param> public ReedSolomonEncoder(GF256 field) { if (!GF256.QR_CODE_FIELD.Equals(field)) { throw new NotSupportedException("Only QR Code is supported at this time"); } this.field = field; this.cachedGenerators = new List <GF256Poly>(); cachedGenerators.Add(new GF256Poly(field, new int[] { 1 })); }