Crc32.cs
上传用户:huiyue
上传日期:2022-04-08
资源大小:1429k
文件大小:4k
- // Crc32.cs
- //
- // Copyright (c) 2006, 2007 Microsoft Corporation. All rights reserved.
- //
- //
- // 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>
- [CLSCompliant(false)]
- 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>
- [CLSCompliant(false)]
- 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;
- }
- }
- }
- }
- }