CRC-32 with reversed data and unreversed output
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRC's on data a byte at a time for all combinations of CRC register values and incoming bytes.
Inheritance: IChecksum
Example #1
0
        public void CRC_32()
        {
            var underTestCrc32 = new Crc32();
            Assert.AreEqual(0x0, underTestCrc32.Value);

            underTestCrc32.Update(check);
            Assert.AreEqual(0xCBF43926, underTestCrc32.Value);

            underTestCrc32.Reset();
            Assert.AreEqual(0x0, underTestCrc32.Value);

            exceptionTesting(underTestCrc32);
        }
        bool ReadHeader()
        {
            // Initialize CRC for this block
            crc = new Crc32();

            // Make sure there is data in file. We can't rely on ReadLeByte() to fill the buffer, as this could be EOF,
            // which is fine, but ReadLeByte() throws an exception if it doesn't find data, so we do this part ourselves.
            if (inputBuffer.Available <= 0) {
                inputBuffer.Fill();
                if (inputBuffer.Available <= 0) {
                    // No header, EOF.
                    return false;
                }
            }

            // 1. Check the two magic bytes
            var headCRC = new Crc32();
            int magic = inputBuffer.ReadLeByte();

            if (magic < 0) {
                throw new EndOfStreamException("EOS reading GZIP header");
            }

            headCRC.Update(magic);
            if (magic != (GZipConstants.GZIP_MAGIC >> 8)) {
                throw new GZipException("Error GZIP header, first magic byte doesn't match");
            }

            //magic = baseInputStream.ReadByte();
            magic = inputBuffer.ReadLeByte();

            if (magic < 0) {
                throw new EndOfStreamException("EOS reading GZIP header");
            }

            if (magic != (GZipConstants.GZIP_MAGIC & 0xFF)) {
                throw new GZipException("Error GZIP header,  second magic byte doesn't match");
            }

            headCRC.Update(magic);

            // 2. Check the compression type (must be 8)
            int compressionType = inputBuffer.ReadLeByte();

            if (compressionType < 0) {
                throw new EndOfStreamException("EOS reading GZIP header");
            }

            if (compressionType != 8) {
                throw new GZipException("Error GZIP header, data not in deflate format");
            }
            headCRC.Update(compressionType);

            // 3. Check the flags
            int flags = inputBuffer.ReadLeByte();
            if (flags < 0) {
                throw new EndOfStreamException("EOS reading GZIP header");
            }
            headCRC.Update(flags);

            /*    This flag byte is divided into individual bits as follows:

            bit 0   FTEXT
            bit 1   FHCRC
            bit 2   FEXTRA
            bit 3   FNAME
            bit 4   FCOMMENT
            bit 5   reserved
            bit 6   reserved
            bit 7   reserved
            */

            // 3.1 Check the reserved bits are zero

            if ((flags & 0xE0) != 0) {
                throw new GZipException("Reserved flag bits in GZIP header != 0");
            }

            // 4.-6. Skip the modification time, extra flags, and OS type
            for (int i = 0; i < 6; i++) {
                int readByte = inputBuffer.ReadLeByte();
                if (readByte < 0) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }
                headCRC.Update(readByte);
            }

            // 7. Read extra field
            if ((flags & GZipConstants.FEXTRA) != 0) {

                // XLEN is total length of extra subfields, we will skip them all
                int len1, len2;
                len1 = inputBuffer.ReadLeByte();
                len2 = inputBuffer.ReadLeByte();
                if ((len1 < 0) || (len2 < 0)) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }
                headCRC.Update(len1);
                headCRC.Update(len2);

                int extraLen = (len2 << 8) | len1;      // gzip is LSB first
                for (int i = 0; i < extraLen; i++) {
                    int readByte = inputBuffer.ReadLeByte();
                    if (readByte < 0) {
                        throw new EndOfStreamException("EOS reading GZIP header");
                    }
                    headCRC.Update(readByte);
                }
            }

            // 8. Read file name
            if ((flags & GZipConstants.FNAME) != 0) {
                int readByte;
                while ((readByte = inputBuffer.ReadLeByte()) > 0) {
                    headCRC.Update(readByte);
                }

                if (readByte < 0) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }
                headCRC.Update(readByte);
            }

            // 9. Read comment
            if ((flags & GZipConstants.FCOMMENT) != 0) {
                int readByte;
                while ((readByte = inputBuffer.ReadLeByte()) > 0) {
                    headCRC.Update(readByte);
                }

                if (readByte < 0) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }

                headCRC.Update(readByte);
            }

            // 10. Read header CRC
            if ((flags & GZipConstants.FHCRC) != 0) {
                int tempByte;
                int crcval = inputBuffer.ReadLeByte();
                if (crcval < 0) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }

                tempByte = inputBuffer.ReadLeByte();
                if (tempByte < 0) {
                    throw new EndOfStreamException("EOS reading GZIP header");
                }

                crcval = (crcval << 8) | tempByte;
                if (crcval != ((int)headCRC.Value & 0xffff)) {
                    throw new GZipException("Header CRC value mismatch");
                }
            }

            readGZIPHeader = true;
            return true;
        }
Example #3
0
        public RuntimeInfo(CompressionMethod method, int compressionLevel,
			int size, string password, bool getCrc)
        {
            this.method = method;
            this.compressionLevel = compressionLevel;
            this.password = password;
            this.size = size;
            this.random = false;

            original = new byte[Size];
            if (random) {
                var rnd = new Random();
                rnd.NextBytes(original);
            } else {
                for (int i = 0; i < size; ++i) {
                    original[i] = (byte)'A';
                }
            }

            if (getCrc) {
                var crc32 = new Crc32();
                crc32.Update(original, 0, size);
                crc = crc32.Value;
            }
        }
        /// <summary>
        /// Closes the zip input stream
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            internalReader = new ReadDataHandler(ReadingNotAvailable);
            crc = null;
            entry = null;

            base.Dispose(disposing);
        }