程式碼
using System; using System.Collections; using System.IO; using System.Security.Cryptography; namespace CodeProject { ////// /// public class CRC32 : HashAlgorithm { protected static uint AllOnes = 0xffffffff; protected static Hashtable cachedCRC32Tables; protected static bool autoCache; protected uint[] crc32Table; private uint m_crc; ////// Returns the default polynomial (used in WinZip, Ethernet, etc) /// public static uint DefaultPolynomial { get { return 0x04C11DB7; } } ////// Gets or sets the auto-cache setting of this class. /// public static bool AutoCache { get { return autoCache; } set { autoCache = value; } } ////// Initialize the cache /// static CRC32() { cachedCRC32Tables = Hashtable.Synchronized( new Hashtable() ); autoCache = true; } public static void ClearCache() { cachedCRC32Tables.Clear(); } ////// Builds a crc32 table given a polynomial /// /// ///protected static uint[] BuildCRC32Table( uint ulPolynomial ) { uint dwCrc; uint[] table = new uint[256]; // 256 values representing ASCII character codes. for (int i = 0; i < 256; i++) { dwCrc = (uint)i; for (int j = 8; j > 0; j--) { if((dwCrc & 1) == 1) dwCrc = (dwCrc >> 1) ^ ulPolynomial; else dwCrc >>= 1; } table[i] = dwCrc; } return table; } /// /// Creates a CRC32 object using the DefaultPolynomial /// public CRC32() : this(DefaultPolynomial) { } ////// Creates a CRC32 object using the specified Creates a CRC32 object /// public CRC32(uint aPolynomial) : this(aPolynomial, CRC32.AutoCache) { } ////// Construct the /// public CRC32(uint aPolynomial, bool cacheTable) { this.HashSizeValue = 32; crc32Table = (uint []) cachedCRC32Tables[aPolynomial]; if ( crc32Table == null ) { crc32Table = CRC32.BuildCRC32Table(aPolynomial); if ( cacheTable ) cachedCRC32Tables.Add( aPolynomial, crc32Table ); } Initialize(); } ////// Initializes an implementation of HashAlgorithm. /// public override void Initialize() { m_crc = AllOnes; } ////// /// /// /// /// protected override void HashCore(byte[] buffer, int offset, int count) { // Save the text in the buffer. for (int i = offset; i < count; i++) { ulong tabPtr = (m_crc & 0xFF) ^ buffer[i]; m_crc >>= 8; m_crc ^= crc32Table[tabPtr]; } } ////// /// ///protected override byte[] HashFinal() { byte [] finalHash = new byte [ 4 ]; ulong finalCRC = m_crc ^ AllOnes; finalHash[0] = (byte) ((finalCRC >> 24) & 0xFF); finalHash[1] = (byte) ((finalCRC >> 16) & 0xFF); finalHash[2] = (byte) ((finalCRC >> 8) & 0xFF); finalHash[3] = (byte) ((finalCRC >> 0) & 0xFF); return finalHash; } /// /// Computes the hash value for the specified Stream. /// new public byte[] ComputeHash(Stream inputStream) { byte [] buffer = new byte [4096]; int bytesRead; while ( (bytesRead = inputStream.Read(buffer, 0, 4096)) > 0 ) { HashCore(buffer, 0, bytesRead); } return HashFinal(); } ////// Overloaded. Computes the hash value for the input data. /// new public byte[] ComputeHash(byte[] buffer) { return ComputeHash(buffer, 0, buffer.Length); } ////// Overloaded. Computes the hash value for the input data. /// /// /// /// ///new public byte[] ComputeHash( byte[] buffer, int offset, int count ) { HashCore(buffer, offset, count); return HashFinal(); } } }
沒有留言:
張貼留言