/// <summary> /// The multiply. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly"/>. /// </returns> public QrGaloisFieldPoly Multiply(QrGaloisFieldPoly other) { if (this.IsZero() || other.IsZero()) { return(this.field.Zero); } int[] galoisACoefficients = this.coefficients; int galoisALength = galoisACoefficients.Length; int[] galoisBCoefficients = other.coefficients; int galoisBLength = galoisBCoefficients.Length; int[] product = new int[galoisALength + galoisBLength - 1]; for (int i = 0; i < galoisALength; i++) { int galoisACoeff = galoisACoefficients[i]; for (int j = 0; j < galoisBLength; j++) { product[i + j] = QrGaloisField.AddOrSubtract(product[i + j], this.field.Multiply(galoisACoeff, galoisBCoefficients[j])); } } return(new QrGaloisFieldPoly(this.field, product)); }
/// <summary> /// The initialization method. /// </summary> private void Init() { this.antiLogTable = new int[this.size]; this.logTable = new int[this.size]; int x = 1; for (int i = 0; i < this.size; i++) { this.antiLogTable[i] = x; x = x << 1; if (x >= this.size) { x ^= this.primitive; x &= this.size - 1; } } for (int i = 0; i < this.size - 1; i++) { this.logTable[this.antiLogTable[i]] = i; } // LogTable[0] should never be used this.Zero = new QrGaloisFieldPoly(this, new[] { 0 }); this.One = new QrGaloisFieldPoly(this, new[] { 1 }); }
/// <summary> /// The calculate method. /// </summary> /// <param name="message"> /// The message. /// </param> /// <param name="numEcc"> /// The number of <c>ecc</c> codes. /// </param> /// <returns> /// The <see cref="byte"/> array. /// </returns> public byte[] Calculate(Poly message, int numEcc) { // Get message poly coefficients int[] messageCoefficients = new int[message.Terms.Length]; for (int i = 0; i < message.Terms.Length; i++) { messageCoefficients[i] = message.Terms[i].Coefficient; } // Convert message poly coefficients into Galois Field (get a coefficients from numbers) QrGaloisFieldPoly info = new QrGaloisFieldPoly(this.field, messageCoefficients); // Increase level of the poly by number of ECC info = info.MultiplyByMonomial(numEcc, 1); // Get generator poly QrGaloisFieldPoly generatorPoly = this.BuildGeneratorPolynomial(numEcc); // Divite by generator poly QrGaloisFieldPoly remainder = info.Divide(generatorPoly)[1]; // Return remainder coefficients in bytes int[] coefficients = remainder.GetCoefficients(); byte[] eccCodes = new byte[coefficients.Length]; for (int i = 0; i < coefficients.Length; i++) { eccCodes[i] = Convert.ToByte(coefficients[i]); } return(eccCodes); }
/// <summary> /// The calculate method. /// </summary> /// <param name="message"> /// The message. /// </param> /// <param name="numEcc"> /// The number of <c>ecc</c> codes. /// </param> /// <returns> /// The <see cref="byte"/> array. /// </returns> public byte[] Calculate(Poly message, int numEcc) { // Get message poly coefficients int[] messageCoefficients = new int[message.Terms.Length]; for (int i = 0; i < message.Terms.Length; i++) { messageCoefficients[i] = message.Terms[i].Coefficient; } // Convert message poly coefficients into Galois Field (get a coefficients from numbers) QrGaloisFieldPoly info = new QrGaloisFieldPoly(this.field, messageCoefficients); // Increase level of the poly by number of ECC info = info.MultiplyByMonomial(numEcc, 1); // Get generator poly QrGaloisFieldPoly generatorPoly = this.BuildGeneratorPolynomial(numEcc); // Divite by generator poly QrGaloisFieldPoly remainder = info.Divide(generatorPoly)[1]; // Return remainder coefficients in bytes int[] coefficients = remainder.GetCoefficients(); byte[] eccCodes = new byte[coefficients.Length]; for (int i = 0; i < coefficients.Length; i++) { eccCodes[i] = Convert.ToByte(coefficients[i]); } return eccCodes; }
/// <summary> /// The divide. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly" /> array. /// </returns> /// <exception cref="ArgumentException"> /// Exception if division by zero. /// </exception> public QrGaloisFieldPoly[] Divide(QrGaloisFieldPoly other) { if (other.IsZero()) { throw new ArgumentException("Divide by 0"); } QrGaloisFieldPoly quotient = this.field.Zero; QrGaloisFieldPoly remainder = this; int denominatorLeadingTerm = other.GetCoefficient(other.GetPower()); int inverseDenominatorLeadingTerm = this.field.Inverse(denominatorLeadingTerm); while ((remainder.GetPower() >= other.GetPower()) && !remainder.IsZero()) { int powerDifference = remainder.GetPower() - other.GetPower(); int scale = this.field.Multiply( remainder.GetCoefficient(remainder.GetPower()), inverseDenominatorLeadingTerm); QrGaloisFieldPoly term = other.MultiplyByMonomial(powerDifference, scale); QrGaloisFieldPoly iterationQuotient = this.field.BuildMonomial(powerDifference, scale); quotient = quotient.AddOrSubtract(iterationQuotient); remainder = remainder.AddOrSubtract(term); } return(new[] { quotient, remainder }); }
/// <summary> /// The add or subtract. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly"/>. /// </returns> public QrGaloisFieldPoly AddOrSubtract(QrGaloisFieldPoly other) { if (this.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-power polynomial's coefficients Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff); for (int i = lengthDiff; i < largerCoefficients.Length; i++) { sumDiff[i] = QrGaloisField.AddOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return(new QrGaloisFieldPoly(this.field, sumDiff)); }
/// <summary> /// The build generator polynomial. /// </summary> /// <param name="power"> /// The power. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly"/>. /// </returns> private QrGaloisFieldPoly BuildGeneratorPolynomial(int power) { if (power >= this.generatorCache.Count) { QrGaloisFieldPoly lastGenerator = this.generatorCache[this.generatorCache.Count - 1]; for (int i = this.generatorCache.Count; i <= power; i++) { QrGaloisFieldPoly nextGenerator = lastGenerator.Multiply( new QrGaloisFieldPoly(this.field, new[] { 1, this.field.GetExponent(i - 1) })); this.generatorCache.Add(nextGenerator); lastGenerator = nextGenerator; } } return(this.generatorCache[power]); }
/// <summary> /// The initialization method. /// </summary> private void Init() { this.antiLogTable = new int[this.size]; this.logTable = new int[this.size]; int x = 1; for (int i = 0; i < this.size; i++) { this.antiLogTable[i] = x; x = x << 1; if (x >= this.size) { x ^= this.primitive; x &= this.size - 1; } } for (int i = 0; i < this.size - 1; i++) { this.logTable[this.antiLogTable[i]] = i; } // LogTable[0] should never be used this.Zero = new QrGaloisFieldPoly(this, new[] { 0 }); this.One = new QrGaloisFieldPoly(this, new[] { 1 }); }
/// <summary> /// The multiply. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly"/>. /// </returns> public QrGaloisFieldPoly Multiply(QrGaloisFieldPoly other) { if (this.IsZero() || other.IsZero()) { return this.field.Zero; } int[] galoisACoefficients = this.coefficients; int galoisALength = galoisACoefficients.Length; int[] galoisBCoefficients = other.coefficients; int galoisBLength = galoisBCoefficients.Length; int[] product = new int[galoisALength + galoisBLength - 1]; for (int i = 0; i < galoisALength; i++) { int galoisACoeff = galoisACoefficients[i]; for (int j = 0; j < galoisBLength; j++) { product[i + j] = QrGaloisField.AddOrSubtract(product[i + j], this.field.Multiply(galoisACoeff, galoisBCoefficients[j])); } } return new QrGaloisFieldPoly(this.field, product); }
/// <summary> /// The divide. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly" /> array. /// </returns> /// <exception cref="ArgumentException"> /// Exception if division by zero. /// </exception> public QrGaloisFieldPoly[] Divide(QrGaloisFieldPoly other) { if (other.IsZero()) { throw new ArgumentException("Divide by 0"); } QrGaloisFieldPoly quotient = this.field.Zero; QrGaloisFieldPoly remainder = this; int denominatorLeadingTerm = other.GetCoefficient(other.GetPower()); int inverseDenominatorLeadingTerm = this.field.Inverse(denominatorLeadingTerm); while ((remainder.GetPower() >= other.GetPower()) && !remainder.IsZero()) { int powerDifference = remainder.GetPower() - other.GetPower(); int scale = this.field.Multiply( remainder.GetCoefficient(remainder.GetPower()), inverseDenominatorLeadingTerm); QrGaloisFieldPoly term = other.MultiplyByMonomial(powerDifference, scale); QrGaloisFieldPoly iterationQuotient = this.field.BuildMonomial(powerDifference, scale); quotient = quotient.AddOrSubtract(iterationQuotient); remainder = remainder.AddOrSubtract(term); } return new[] { quotient, remainder }; }
/// <summary> /// The add or subtract. /// </summary> /// <param name="other"> /// The other. /// </param> /// <returns> /// The <see cref="QrGaloisFieldPoly"/>. /// </returns> public QrGaloisFieldPoly AddOrSubtract(QrGaloisFieldPoly other) { if (this.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-power polynomial's coefficients Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff); for (int i = lengthDiff; i < largerCoefficients.Length; i++) { sumDiff[i] = QrGaloisField.AddOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return new QrGaloisFieldPoly(this.field, sumDiff); }