Example #1
0
        public static BitList GenerateCheckWords(BitList bits, int totalBits, int wordSize)
        {
            var rs = new ReedSolomonEncoder(GetGaloisField(wordSize));

            // bits is guaranteed to be a multiple of the wordSize, so no padding needed
            int messageWordCount = bits.Length / wordSize;
            int totalWordCount   = totalBits / wordSize;
            int eccWordCount     = totalWordCount - messageWordCount;

            int[] messageWords = BitsToWords(bits, wordSize, messageWordCount);
            int[] eccWords     = rs.Encode(messageWords, eccWordCount);
            int   startPad     = totalBits % wordSize;

            var messageBits = new BitList();

            messageBits.AddBits(0, (byte)startPad);

            foreach (var messageWord in messageWords)
            {
                messageBits.AddBits((uint)messageWord, (byte)wordSize);
            }

            foreach (var eccWord in eccWords)
            {
                messageBits.AddBits((uint)eccWord, (byte)wordSize);
            }

            return(messageBits);
        }
Example #2
0
        public static byte[] CalculateEcc(byte[] data, CodeSize size)
        {
            var dataSize = data.Length;
            var result   = new byte[data.Length + size.EccCount];

            Array.Copy(data, result, data.Length);

            for (int block = 0; block < size.BlockCount; block++)
            {
                var dataCnt = size.DataCodewordsForBlock(block);
                var buff    = new int[dataCnt];
                // copy the data for the current block to buff
                var j = 0;
                for (int i = block; i < dataSize; i += size.BlockCount)
                {
                    buff[j] = result[i];
                    j++;
                }
                // calc the error correction codes
                var ecc = ReedSolomonEncoder.Encode(buff, size.ErrorCorrectionCodewordsPerBlock);
                // and append them to the result
                j = 0;
                for (int i = block; i < size.ErrorCorrectionCodewordsPerBlock * size.BlockCount; i += size.BlockCount)
                {
                    result[dataSize + i] = (byte)ecc[j];
                    j++;
                }
            }

            return(result);
        }
Example #3
0
        private void TestOneCase(byte[] data, int ecLength, byte[] expectResult)
        {
            byte[] result = ReedSolomonEncoder.Encode(data, ecLength, m_cacheGeneratorPoly);

            if (!PolynomialExtensions.isEqual(result, expectResult))
            {
                Assert.Fail("Remainder not same. result {0}, expect {1}", result.Length, expectResult.Length);
            }
        }
Example #4
0
        public static byte[] CalculateEcc(byte[] data, byte eccCount)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            var dataInts = data.Select(x => (int)x).ToArray();

            int[] res = ReedSolomonEncoder.Encode(dataInts, eccCount);
            return(res.Select(x => (byte)x).ToArray());
        }
Example #5
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]);
        }
Example #6
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);
        }
Example #7
0
        public void Encode(int[] plainData, int erasures)
        {
            var rse = new ReedSolomonEncoder(_field);

            rse.Encode(plainData, erasures);
        }