Пример #1
0
        private void IntellgentMail()
        {
            int       index;
            int       value;
            string    zip      = String.Empty;
            string    tracker  = String.Empty;
            BitVector zipAdder = new BitVector();

            short[] accumulator = new short[112];
            short[] xRegister   = new short[112];
            short[] yRegister   = new short[112];
            byte[]  byteData    = new byte[13];
            uint    uspsCRC;

            int[]         codeword    = new int[10];
            uint[]        characters  = new uint[10];
            int[]         barMap      = new int[130];
            StringBuilder barPattern  = new StringBuilder();
            int           inputLength = barcodeData.Length;

            if (inputLength > 31)
            {
                throw new InvalidDataLengthException("USPS: Input data too long.");
            }

            if (inputLength < 20)
            {
                throw new InvalidDataLengthException("USPS: Invalid tracking code length.");
            }

            // Separate the tracking code from the routing code.
            tracker = new string(barcodeData, 0, 20);
            if (inputLength > 20)
            {
                zip = new string(barcodeData, 20, inputLength - tracker.Length);
            }

            if (zip.Length != 11 && zip.Length != 9 && zip.Length != 5 && zip.Length != 0)
            {
                throw new InvalidDataException("USPS: Invalid ZIP code.");
            }

            Array.Clear(accumulator, 0, 112);
            for (index = 0; index < zip.Length; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(xRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = zip[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        xRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, xRegister);
            }

            // Add weight to routing code.
            Array.Copy(accumulator, xRegister, 112);
            if (zip.Length > 9)
            {
                zipAdder.AppendBits(545, 10);       // 1000100001
            }
            else
            {
                if (zip.Length > 5)
                {
                    zipAdder.AppendBits(33, 6);     // 100001
                }
                else
                {
                    if (zip.Length > 0)
                    {
                        zipAdder.AppendBit(1);      // 1
                    }
                    else
                    {
                        zipAdder.AppendBit(0);      // 0
                    }
                }
            }

            Array.Clear(accumulator, 0, 112);
            for (index = 0; index < zipAdder.SizeInBits; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(yRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = zipAdder[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        yRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, yRegister);
            }

            BinaryMath.BinaryAdd(accumulator, xRegister);

            // Tracking code.
            // Multiply by 10.
            BinaryMath.BinaryMultiply(accumulator, "10");
            BinaryMath.BinaryLoad(yRegister, "0");
            for (int i = 0; i < 4; i++)
            {
                value = tracker[0] - '0';
                if ((value & (0x01 << i)) > 0)
                {
                    yRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(accumulator, yRegister);

            // Multiply by 5.
            BinaryMath.BinaryMultiply(accumulator, "5");
            BinaryMath.BinaryLoad(yRegister, "0");
            // Add second digit.
            for (int i = 0; i < 4; i++)
            {
                value = tracker[1] - '0';
                if ((value & (0x01 << i)) > 0)
                {
                    yRegister[i] = 1;
                }
            }

            BinaryMath.BinaryAdd(accumulator, yRegister);

            // And then the rest.
            for (index = 2; index < tracker.Length; index++)
            {
                BinaryMath.BinaryMultiply(accumulator, "10");
                BinaryMath.BinaryLoad(yRegister, "0");
                for (int i = 0; i < 4; i++)
                {
                    value = tracker[index] - '0';
                    if ((value & (0x01 << i)) > 0)
                    {
                        yRegister[i] = 1;
                    }
                }

                BinaryMath.BinaryAdd(accumulator, yRegister);
            }

            // Step 2 - Generation of 11-bit CRC on Binary Data.
            accumulator[103] = 0;
            accumulator[102] = 0;

            for (int i = 0; i < 13; i++)
            {
                int j = 96 - (8 * i);
                byteData[i]  = 0;
                byteData[i] += (byte)accumulator[j];
                byteData[i] += (byte)(2 * accumulator[j + 1]);
                byteData[i] += (byte)(4 * accumulator[j + 2]);
                byteData[i] += (byte)(8 * accumulator[j + 3]);
                byteData[i] += (byte)(16 * accumulator[j + 4]);
                byteData[i] += (byte)(32 * accumulator[j + 5]);
                byteData[i] += (byte)(64 * accumulator[j + 6]);
                byteData[i] += (byte)(128 * accumulator[j + 7]);
            }

            uspsCRC = CRC11GenerateFrameCheckSequence(byteData);

            // Step 3 - Conversion from Binary Data to Codewords.
            // Start with codeword J which is base 636
            Array.Clear(xRegister, 0, 112);
            Array.Clear(yRegister, 0, 112);

            xRegister[101] = 1;
            xRegister[98]  = 1;
            xRegister[97]  = 1;
            xRegister[96]  = 1;
            xRegister[95]  = 1;
            xRegister[94]  = 1;

            for (int i = 92; i >= 0; i--)
            {
                yRegister[i] = BinaryMath.IsLarger(accumulator, xRegister);
                if (yRegister[i] == 1)
                {
                    BinaryMath.BinarySubtract(accumulator, xRegister);
                }

                BinaryMath.ShiftDown(xRegister);
            }

            codeword[9] = (accumulator[9] * 512) + (accumulator[8] * 256) + (accumulator[7] * 128) + (accumulator[6] * 64) +
                          (accumulator[5] * 32) + (accumulator[4] * 16) + (accumulator[3] * 8) + (accumulator[2] * 4) +
                          (accumulator[1] * 2) + accumulator[0];

            // Then codewords I to B with base 1365.
            for (int j = 8; j > 0; j--)
            {
                for (int i = 0; i < 112; i++)
                {
                    accumulator[i] = yRegister[i];
                    yRegister[i]   = 0;
                    xRegister[i]   = 0;
                }

                xRegister[101] = 1;
                xRegister[99]  = 1;
                xRegister[97]  = 1;
                xRegister[95]  = 1;
                xRegister[93]  = 1;
                xRegister[91]  = 1;
                for (int i = 91; i >= 0; i--)
                {
                    yRegister[i] = BinaryMath.IsLarger(accumulator, xRegister);
                    if (yRegister[i] == 1)
                    {
                        BinaryMath.BinarySubtract(accumulator, xRegister);
                    }

                    BinaryMath.ShiftDown(xRegister);
                }

                codeword[j] = (accumulator[10] * 1024) + (accumulator[9] * 512) + (accumulator[8] * 256) +
                              (accumulator[7] * 128) + (accumulator[6] * 64) + (accumulator[5] * 32) +
                              (accumulator[4] * 16) + (accumulator[3] * 8) + (accumulator[2] * 4) +
                              (accumulator[1] * 2) + accumulator[0];
            }

            codeword[0] = (yRegister[10] * 1024) + (yRegister[9] * 512) + (yRegister[8] * 256) +
                          (yRegister[7] * 128) + (yRegister[6] * 64) + (yRegister[5] * 32) +
                          (yRegister[4] * 16) + (yRegister[3] * 8) + (yRegister[2] * 4) +
                          (yRegister[1] * 2) + yRegister[0];

            for (int i = 0; i < 8; i++)
            {
                if (codeword[i] == 1365)
                {
                    codeword[i] = 0;
                    codeword[i + 1]++;
                }
            }

            // Step 4 - Inserting Additional Information into Codewords.
            codeword[9] = codeword[9] * 2;
            if (uspsCRC >= 1024)
            {
                codeword[0] += 659;
            }

            // Step 5 - Conversion from Codewords to Characters.
            for (int i = 0; i < 10; i++)
            {
                if (codeword[i] < 1287)
                {
                    characters[i] = AppendixD1[codeword[i]];
                }

                else
                {
                    characters[i] = AppendixD2[codeword[i] - 1287];
                }
            }

            for (int i = 0; i < 10; i++)
            {
                if ((uspsCRC & (1 << i)) > 0)
                {
                    characters[i] = 0x1FFF - characters[i];
                }
            }

            // Step 6 - Conversion from Characters to the Intelligent Mail Barcode.
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 13; j++)
                {
                    if ((characters[i] & (1 << j)) > 0)
                    {
                        barMap[AppendixD4[(13 * i) + j] - 1] = 1;
                    }

                    else
                    {
                        barMap[AppendixD4[(13 * i) + j] - 1] = 0;
                    }
                }
            }

            for (int i = 0; i < 65; i++)
            {
                int j = 0;
                if (barMap[i] == 0)
                {
                    j += 1;
                }

                if (barMap[i + 65] == 0)
                {
                    j += 2;
                }

                barPattern.Append(j);
            }

            SymbolBuilder.BuildFourStateSymbol(Symbol, barPattern);
            // Format the barcodes text.
            barcodeText = new string(barcodeData);
            if (zip.Length > 0)
            {
                if (zip.Length == 11)
                {
                    barcodeText = barcodeText.Insert(29, " ");
                }

                if (zip.Length >= 9)
                {
                    barcodeText = barcodeText.Insert(25, " ");
                }

                if (zip.Length >= 5)
                {
                    barcodeText = barcodeText.Insert(20, " ");
                }
            }

            if (tracker[5] < '9')
            {
                barcodeText = barcodeText.Insert(11, " ");
            }

            else
            {
                barcodeText = barcodeText.Insert(14, " ");
            }

            barcodeText = barcodeText.Insert(5, " ");
            barcodeText = barcodeText.Insert(2, " ");
        }