Mega Code Archive

 
Categories / C# / Security
 

Calculates a 32 bit Cyclic Redundancy Checksum (CRC) using the same polynomial used by Zip

// Crc32.cs // // Implements the CRC algorithm, which is used in zip files.  The zip format calls for // the zipfile to contain a CRC for the unencrypted byte stream of each file. // // It is based on example source code published at //    http://www.vbaccelerator.com/home/net/code/libraries/CRC32/Crc32_zip_CRC32_CRC32_cs.asp // // This implementation adds a tweak of that code for use within zip creation.  While // computing the CRC we also compress the byte stream, in the same read loop. This // avoids the need to read through the uncompressed stream twice - once to computer CRC // and another time to compress. // // // Thu, 30 Mar 2006  13:58 //  using System; namespace ionic.utils.zip {   /// <summary>   /// Calculates a 32bit Cyclic Redundancy Checksum (CRC) using the   /// same polynomial used by Zip.   /// </summary>   public class CRC32   {     private UInt32[] crc32Table;     private const int BUFFER_SIZE = 8192;     private Int32 _TotalBytesRead = 0;     public Int32 TotalBytesRead     {       get       {         return _TotalBytesRead;       }     }     /// <summary>     /// Returns the CRC32 for the specified stream.     /// </summary>     /// <param name="input">The stream over which to calculate the CRC32</param>     /// <returns>the CRC32 calculation</returns>     public UInt32 GetCrc32(System.IO.Stream input)     {       return GetCrc32AndCopy(input, null);     }     /// <summary>     /// Returns the CRC32 for the specified stream, and writes the input into the output stream.     /// </summary>     /// <param name="input">The stream over which to calculate the CRC32</param>     /// <param name="output">The stream into which to deflate the input</param>     /// <returns>the CRC32 calculation</returns>     public UInt32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output)     {       unchecked       {         UInt32 crc32Result;         crc32Result = 0xFFFFFFFF;         byte[] buffer = new byte[BUFFER_SIZE];         int readSize = BUFFER_SIZE;         _TotalBytesRead = 0;         int count = input.Read(buffer, 0, readSize);         if (output != null) output.Write(buffer, 0, count);         _TotalBytesRead += count;         while (count > 0)         {           for (int i = 0; i < count; i++)           {             crc32Result = ((crc32Result) >> 8) ^ crc32Table[(buffer[i]) ^ ((crc32Result) & 0x000000FF)];           }           count = input.Read(buffer, 0, readSize);           if (output != null) output.Write(buffer, 0, count);           _TotalBytesRead += count;         }         return ~crc32Result;       }     }     /// <summary>     /// Construct an instance of the CRC32 class, pre-initialising the table     /// for speed of lookup.     /// </summary>     public CRC32()     {       unchecked       {         // This is the official polynomial used by CRC32 in PKZip.         // Often the polynomial is shown reversed as 0x04C11DB7.         UInt32 dwPolynomial = 0xEDB88320;         UInt32 i, j;         crc32Table = new UInt32[256];         UInt32 dwCrc;         for (i = 0; i < 256; i++)         {           dwCrc = i;           for (j = 8; j > 0; j--)           {             if ((dwCrc & 1) == 1)             {               dwCrc = (dwCrc >> 1) ^ dwPolynomial;             }             else             {               dwCrc >>= 1;             }           }           crc32Table[i] = dwCrc;         }       }     }   } }