Click here to Skip to main content
15,881,898 members
Articles / Mobile Apps

CrcStream stream checksum calculator

Rate me:
Please Sign up or sign in to vote.
4.66/5 (23 votes)
8 Oct 2005CPOL1 min read 125.1K   2K   43  
Make better use of time by calculating CRCs on-the-fly.
using System;
using System.IO;

namespace CodeProject.ReiMiyasaka
{
	/// <summary>
	/// Encapsulates a <see cref="System.IO.Stream" /> to calculate the CRC32 checksum on-the-fly as data passes through.
	/// </summary>
	public class CrcStream : Stream
	{
		/// <summary>
		/// Encapsulate a <see cref="System.IO.Stream" />.
		/// </summary>
		/// <param name="stream">The stream to calculate the checksum for.</param>
		public CrcStream(Stream stream)
		{
			this.stream = stream;
		}

		Stream stream;

		/// <summary>
		/// Gets the underlying stream.
		/// </summary>
		public Stream Stream
		{
			get { return stream; }
		}

		public override bool CanRead
		{
			get { return stream.CanRead; }
		}

		public override bool CanSeek
		{
			get { return stream.CanSeek; }
		}

		public override bool CanWrite
		{
			get { return stream.CanWrite; }
		}

		public override void Flush()
		{
			stream.Flush();
		}

		public override long Length
		{
			get { return stream.Length; }
		}

		public override long Position
		{
			get
			{
				return stream.Position;
			}
			set
			{
				stream.Position = value;
			}
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return stream.Seek(offset, origin);
		}

		public override void SetLength(long value)
		{
			stream.SetLength(value);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			count = stream.Read(buffer, offset, count);
			readCrc = CalculateCrc(readCrc, buffer, offset, count);
			return count;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			stream.Write(buffer, offset, count);

			writeCrc = CalculateCrc(writeCrc, buffer, offset, count);
		}

		uint CalculateCrc(uint crc, byte[] buffer, int offset, int count)
		{
			unchecked
			{
				for (int i = offset, end = offset + count; i < end; i++)
					crc = (crc >> 8) ^ table[(crc ^ buffer[i]) & 0xFF];
			}
			return crc;
		}

		static private uint[] table = GenerateTable();

		static private uint[] GenerateTable()
		{
			unchecked
			{
				uint[] table = new uint[256];

				uint crc;
				const uint poly = 0xEDB88320;
				for (uint i = 0; i < table.Length; i++)
				{
					crc = i;
					for (int j = 8; j > 0; j--)
					{
						if ((crc & 1) == 1)
							crc = (crc >> 1) ^ poly;
						else
							crc >>= 1;
					}
					table[i] = crc;
				}

				return table;
			}

		}

		uint readCrc = unchecked(0xFFFFFFFF);

		/// <summary>
		/// Gets the CRC checksum of the data that was read by the stream thus far.
		/// </summary>
		public uint ReadCrc
		{
			get { return unchecked(readCrc ^ 0xFFFFFFFF); }
		}

		uint writeCrc = unchecked(0xFFFFFFFF);

		/// <summary>
		/// Gets the CRC checksum of the data that was written to the stream thus far.
		/// </summary>
		public uint WriteCrc
		{
			get { return unchecked(writeCrc ^ 0xFFFFFFFF); }
		}

		/// <summary>
		/// Resets the read and write checksums.
		/// </summary>
		public void ResetChecksum()
		{
			readCrc = unchecked(0xFFFFFFFF);
			writeCrc = unchecked(0xFFFFFFFF);
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
The cows are here to take me home now...

Comments and Discussions