/// <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));
        }
Esempio n. 2
0
        /// <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 });
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 7
0
        /// <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]);
        }
Esempio n. 8
0
        /// <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 });
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        /// <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 };
        }
Esempio n. 11
0
        /// <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);
        }