Click here to Skip to main content
11,478,174 members (70,719 online)
Click here to Skip to main content
Add your own
alternative version

CrcStream stream checksum calculator

, 8 Oct 2005 CPOL 84.3K 1.5K 42
Make better use of time by calculating CRCs on-the-fly.
crcstream.zip
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)

Share

About the Author

Rei Miyasaka

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150520.1 | Last Updated 8 Oct 2005
Article Copyright 2005 by Rei Miyasaka
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid