Exemple #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Polynomial"/> class.
        /// </summary>
        /// <param name="gfield">The gfield.</param>
        /// <param name="coefficients">The coefficients.</param>
        /// <remarks></remarks>
        internal Polynomial(GaloisField256 gfield, int[] coefficients)
        {
            int coefficientsLength = coefficients.Length;

            if (coefficientsLength == 0 || coefficients == null)
                throw new ArithmeticException("Can not create empty Polynomial");

            m_GField = gfield;

            m_primitive = gfield.Primitive;

            if (coefficientsLength > 1 && coefficients[0] == 0)
            {
                int firstNonZeroIndex = 1;
                while (firstNonZeroIndex < coefficientsLength && coefficients[firstNonZeroIndex] == 0)
                {
                    firstNonZeroIndex++;
                }

                if (firstNonZeroIndex == coefficientsLength)
                    m_Coefficients = new[] {0};
                else
                {
                    int newLength = coefficientsLength - firstNonZeroIndex;
                    m_Coefficients = new int[newLength];
                    Array.Copy(coefficients, firstNonZeroIndex, m_Coefficients, 0, newLength);
                }
            }
            else
            {
                m_Coefficients = new int[coefficientsLength];
                Array.Copy(coefficients, m_Coefficients, coefficientsLength);
            }
        }
 /// <summary>
 /// After create GeneratorPolynomial. Keep it as long as possible.
 /// Unless QRCode encode is done or no more QRCode need to generate.
 /// </summary>
 internal GeneratorPolynomial(GaloisField256 gfield)
 {
     Gfield         = gfield;
     CacheGenerator = new List <Polynomial>(10)
     {
         new Polynomial(Gfield, new int[] { 1 })
     };
 }
        /// <summary>
        /// Instantiates a new instance of the Rs256Encoder.
        /// </summary>
        /// <param name="size"></param>
        /// <param name="decodedSize"></param>
        /// <param name="fieldGeneratorPoly"></param>
        public Rs256Encoder(int size, int decodedSize, int fieldGeneratorPoly)
        {
            this.size        = size;
            this.decodedSize = decodedSize;
            this.checkwords  = (size - 1) - decodedSize;

            this.gf            = new GaloisField256(size, fieldGeneratorPoly);
            this.codeGenPoly   = BuildCodeGenPoly();
            this.modTempResult = new byte[this.checkwords];
        }
Exemple #4
0
        public void Test_against_CSV_Dataset(int i, int exp)
        {
            GaloisField256 gfield = GaloisField256.QRCodeGaloisField;

            int result = gfield.Exponent(i);

            if (exp != result)
            {
                Assert.Fail("Fail. request {0} Expect {1} result {2}", i, exp, result);
            }
        }
Exemple #5
0
        public void Test_against_reference_implementation(int i, int exp)
        {
            GaloisField256 gfield = GaloisField256.QRCodeGaloisField;

            int result = gfield.Exponent(i);

            if (exp != result)
            {
                Assert.Fail("Fail. request {0} Expect {1} result {2}", i, exp, result);
            }
        }
Exemple #6
0
        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);
            }
        }
Exemple #7
0
        public void PerformanceTest()
        {
            Random randomizer = new Random();

            sbyte[] zxTestCase = PolynomialExtensions.GenerateSbyteArray(40, randomizer);
            int     ecBytes    = 50;

            byte[] testCase = PolynomialExtensions.ToByteArray(zxTestCase);

            Stopwatch sw          = new Stopwatch();
            int       timesofTest = 10000;

            string[] timeElapsed = new string[2];

            sw.Start();
            GaloisField256      gf256     = GaloisField256.QRCodeGaloisField;
            GeneratorPolynomial generator = new GeneratorPolynomial(gf256);

            for (int i = 0; i < timesofTest; i++)
            {
                ReedSolomonEncoder.Encode(testCase, ecBytes, generator);
            }

            sw.Stop();

            timeElapsed[0] = sw.ElapsedMilliseconds.ToString();

            sw.Reset();

            sw.Start();

            for (int i = 0; i < timesofTest; i++)
            {
                EncoderInternal.generateECBytes(zxTestCase, ecBytes);
            }
            sw.Stop();

            timeElapsed[1] = sw.ElapsedMilliseconds.ToString();


            Assert.Pass("ReedSolomon performance {0} Tests~ QrCode.Net: {1} ZXing: {2}", timesofTest, timeElapsed[0], timeElapsed[1]);
        }
Exemple #8
0
        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);
            }
        }
    internal Polynomial(GaloisField256 gfield, int[] coefficients)
    {
        int coefficientsLength = coefficients.Length;

        if (coefficientsLength == 0 || coefficients is null)
        {
            throw new ArithmeticException($"Cannot create empty {nameof(Polynomial)}.");
        }

        GField = gfield;

        Primitive = gfield.Primitive;

        if (coefficientsLength > 1 && coefficients[0] == 0)
        {
            int firstNonZeroIndex = 1;
            while (firstNonZeroIndex < coefficientsLength && coefficients[firstNonZeroIndex] == 0)
            {
                firstNonZeroIndex++;
            }

            if (firstNonZeroIndex == coefficientsLength)
            {
                Coefficients = new int[] { 0 };
            }
            else
            {
                int newLength = coefficientsLength - firstNonZeroIndex;
                Coefficients = new int[newLength];
                Array.Copy(coefficients, firstNonZeroIndex, Coefficients, 0, newLength);
            }
        }
        else
        {
            Coefficients = new int[coefficientsLength];
            Array.Copy(coefficients, Coefficients, coefficientsLength);
        }
    }
        public Rs256Decoder(int size, int numDataSymbols, int fieldGenPoly)
        {
            this.size           = size;
            this.numDataSymbols = numDataSymbols;
            this.fieldGenPoly   = fieldGenPoly;
            this.numCheckBytes  = (size - 1) - numDataSymbols;

            this.CodeWordSize = size - 1;

            this.gf = new GaloisField256(size, fieldGenPoly);

            // Syndrom calculation buffers
            this.syndroms = new byte[numCheckBytes];

            // Lamda calculation buffers
            this.lambda     = new byte[numCheckBytes - 1];
            this.corrPoly   = new byte[numCheckBytes - 1];
            this.lambdaStar = new byte[numCheckBytes - 1];

            // LambdaPrime calculation buffers
            this.lambdaPrime = new byte[numCheckBytes - 2];

            // Omega calculation buffers
            this.omega = new byte[numCheckBytes - 2];

            // Error position calculation
            this.errorIndexes = new byte[size - 1];

            // Cache of the lookup used in the ChienSearch process.
            this.chienCache = new byte[size - 1];

            for (int i = 0; i < this.chienCache.Length; i++)
            {
                this.chienCache[i] = gf.Inverses[gf.Field[i + 1]];
            }
        }
Exemple #11
0
        /// <summary>
        /// Generate error correction blocks. Then out put with codewords BitList
        /// ISO/IEC 18004/2006 P45, 46. Chapter 6.6 Constructing final message codewords sequence.
        /// </summary>
        /// <param name="dataCodewords">Datacodewords from DataEncodation.DataEncode</param>
        /// <param name="numTotalBytes">Total number of bytes</param>
        /// <param name="numDataBytes">Number of data bytes</param>
        /// <param name="numECBlocks">Number of Error Correction blocks</param>
        /// <returns>codewords BitList contain datacodewords and ECCodewords</returns>
        internal static BitList FillECCodewords(BitList dataCodewords, VersionDetail vd)
        {
            List <byte> dataCodewordsByte  = dataCodewords.List;
            int         ecBlockGroup2      = vd.ECBlockGroup2;
            int         ecBlockGroup1      = vd.ECBlockGroup1;
            int         numDataBytesGroup1 = vd.NumDataBytesGroup1;
            int         numDataBytesGroup2 = vd.NumDataBytesGroup2;

            int ecBytesPerBlock = vd.NumECBytesPerBlock;

            int dataBytesOffset = 0;

            byte[][] dByteJArray  = new byte[vd.NumECBlocks][];
            byte[][] ecByteJArray = new byte[vd.NumECBlocks][];

            GaloisField256      gf256     = GaloisField256.QRCodeGaloisField;
            GeneratorPolynomial generator = new GeneratorPolynomial(gf256);

            for (int blockID = 0; blockID < vd.NumECBlocks; blockID++)
            {
                if (blockID < ecBlockGroup1)
                {
                    dByteJArray[blockID] = new byte[numDataBytesGroup1];
                    for (int index = 0; index < numDataBytesGroup1; index++)
                    {
                        dByteJArray[blockID][index] = dataCodewordsByte[dataBytesOffset + index];
                    }
                    dataBytesOffset += numDataBytesGroup1;
                }
                else
                {
                    dByteJArray[blockID] = new byte[numDataBytesGroup2];
                    for (int index = 0; index < numDataBytesGroup2; index++)
                    {
                        dByteJArray[blockID][index] = dataCodewordsByte[dataBytesOffset + index];
                    }
                    dataBytesOffset += numDataBytesGroup2;
                }

                ecByteJArray[blockID] = ReedSolomonEncoder.Encode(dByteJArray[blockID], ecBytesPerBlock, generator);
            }
            if (vd.NumDataBytes != dataBytesOffset)
            {
                throw new ArgumentException("Data bytes does not match offset");
            }

            BitList codewords = new BitList();

            int maxDataLength = ecBlockGroup1 == vd.NumECBlocks ? numDataBytesGroup1 : numDataBytesGroup2;

            for (int dataID = 0; dataID < maxDataLength; dataID++)
            {
                for (int blockID = 0; blockID < vd.NumECBlocks; blockID++)
                {
                    if (!(dataID == numDataBytesGroup1 && blockID < ecBlockGroup1))
                    {
                        codewords.Add((int)dByteJArray[blockID][dataID], 8);
                    }
                }
            }

            for (int ECID = 0; ECID < ecBytesPerBlock; ECID++)
            {
                for (int blockID = 0; blockID < vd.NumECBlocks; blockID++)
                {
                    codewords.Add((int)ecByteJArray[blockID][ECID], 8);
                }
            }

            if (vd.NumTotalBytes != codewords.Count >> 3)
            {
                throw new ArgumentException(string.Format("total bytes: {0}, actual bits: {1}", vd.NumTotalBytes, codewords.Count));
            }

            return(codewords);
        }