Click here to Skip to main content
15,886,919 members
Articles / Mobile Apps
Article

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.5K   2K   43   23
Make better use of time by calculating CRCs on-the-fly.

Introduction

CRC (Cyclic Redundancy Check) is commonly used as a way to confirm that a file had not corrupted during download. While convenient, it takes some time to read the data off of the disk after downloading for the check. It would be convenient if applications checked the CRC on-the-fly during download, so as not to waste idle CPU time and disk read time.

Downloading is done at a relatively leisurely pace (typically anywhere between 5-300kb/s) and over a long period of time, so it makes for a great opportunity to process data without impeding performance. Although ugly and impractical for most applications (it'd be safe to assume that most users think they've "broken the intarweb" when they see a hex number), displaying the CRC to the user immediately as a download finishes can often be a well-appreciated bonus.

This class passively calculates CRCs as data passes through it, ready to be used at any time.

Using the code

To calculate the CRC of a file as it is read to the end, create a new CrcStream passing the FileStream as an argument, and use the ReadCrc property to retrieve the CRC. Be sure to use the new CrcStream instead of the file stream to read from the file; otherwise the checksum will not be calculated.

C#
//Open a file stream, encapsulate it in CrcStream
FileStream file = new FileStream(filename, FileMode.Open);
CrcStream stream = new CrcStream(file);

//Use the file somehow -- in this case, read it as a string
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();

//Print the checksum
Console.WriteLine("CRC: " + stream.ReadCrc.ToString("X8"));

There are four public members in addition to the abstract Stream overrides:

  • ReadCrc - gets the checksum of the data that was read through the stream.
  • WriteCrc - gets the checksum of the data that was written to the stream.
  • ResetChecksum - resets the CRC values.
  • Stream - gets the encapsulated stream.

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

 
GeneralExcellent! Pin
JonKristian31-Mar-11 22:56
JonKristian31-Mar-11 22:56 
GeneralMy vote of 5 Pin
drago697-Mar-11 20:59
drago697-Mar-11 20:59 
GeneralMy vote of 5 Pin
ChewsHumans6-Sep-10 12:00
ChewsHumans6-Sep-10 12:00 
GeneralRe: My vote of 5 Pin
ChewsHumans6-Sep-10 13:11
ChewsHumans6-Sep-10 13:11 
NewsCrcStream in VB.net Pin
Mike19537-Nov-08 11:16
Mike19537-Nov-08 11:16 
QuestionHow does it handle big files? Pin
rgiejef5-Mar-08 2:27
rgiejef5-Mar-08 2:27 
AnswerRe: How does it handle big files? Pin
Rei Miyasaka5-Mar-08 2:35
Rei Miyasaka5-Mar-08 2:35 
GeneralRe: How does it handle big files? Pin
rgiejef13-Mar-08 1:31
rgiejef13-Mar-08 1:31 
GeneralRe: How does it handle big files? Pin
Rei Miyasaka13-Mar-08 10:05
Rei Miyasaka13-Mar-08 10:05 
GeneralRe: How does it handle big files? Pin
Christian Loft16-Mar-08 21:55
Christian Loft16-Mar-08 21:55 
GeneralRe: How does it handle big files? Pin
Buzz Weetman22-Apr-08 5:01
Buzz Weetman22-Apr-08 5:01 
GeneralRe: How does it handle big files? Pin
Rei Miyasaka22-Apr-08 9:31
Rei Miyasaka22-Apr-08 9:31 
GeneralYet another thank you Pin
zimmerware24-May-07 10:49
zimmerware24-May-07 10:49 
GeneralSmall Enhancement Pin
nerd_biker20-Mar-07 2:37
nerd_biker20-Mar-07 2:37 
GeneralRe: Small Enhancement Pin
Rei Miyasaka20-Mar-07 11:12
Rei Miyasaka20-Mar-07 11:12 
QuestionAdapted Version Pin
FernandoNunes30-Mar-06 2:45
FernandoNunes30-Mar-06 2:45 
Hi mate,

Very nice work On-The-Fly CRC and with the polynomial.

With your class, we can check any type of stream, but if the target are always files, is there a reason why we can't derive it from FileStream and directly implement the CRC on it ?

It avoids using a FileStream to acquire the Stream and then encapsulate that Stream in your own class.
I've tested this changes but i can't get any performance improvements D'Oh! | :doh:

But can you check if this is valid ??
Here's the adaptation:

<br />
    class FileStreamWithCRC : FileStream<br />
    {<br />
        private uint _readCRC = unchecked(0xFFFFFFFF);<br />
        private uint _writeCRC = unchecked(0xFFFFFFFF);<br />
        private static uint[] GenerateTable()<br />
        {<br />
            unchecked<br />
            {<br />
                uint[] table = new uint[256];<br />
<br />
                uint crc;<br />
                const uint poly = 0xEDB88320;<br />
                for (uint i = 0; i < table.Length; i++)<br />
                {<br />
                    crc = i;<br />
                    for (int j = 8; j > 0; j--)<br />
                    {<br />
                        if ((crc & 1) == 1)<br />
                            crc = (crc >> 1) ^ poly;<br />
                        else<br />
                            crc >>= 1;<br />
                    }<br />
                    table[i] = crc;<br />
                }<br />
<br />
                return table;<br />
            }<br />
<br />
        }<br />
<br />
        private static uint[] table = GenerateTable();<br />
<br />
        public uint ReadCRC<br />
        {<br />
            get { return unchecked(this._readCRC ^ 0xFFFFFFFF); }<br />
        }<br />
<br />
        public uint WriteCRC<br />
        {<br />
            get { return unchecked(this._writeCRC ^ 0xFFFFFFFF); }<br />
        }<br />
<br />
        public FileStreamWithCRC(String filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare): base(filePath, fileMode, fileAccess, fileShare)<br />
        {<br />
 <br />
        }<br />
<br />
        // Insert more constructors if needed<br />
        //public FileStreamWithCRC(String filePath, FileMode fileMode) : base(filePath, fileMode)<br />
        //{<br />
        //}<br />
<br />
        uint CalculateCRC(uint crc, byte[] buffer, int offset, int count)<br />
        {<br />
            unchecked<br />
            {<br />
                for (int i = offset, end = offset + count; i < end; i++)<br />
                    crc = (crc >> 8) ^ table[(crc ^ buffer[i]) & 0xFF];<br />
            }<br />
            return crc;<br />
        }<br />
<br />
        public void ResetChecksum()<br />
        {<br />
            this._readCRC = unchecked(0xFFFFFFFF);<br />
            this._writeCRC = unchecked(0xFFFFFFFF);<br />
        }<br />
<br />
        public override int Read(byte[] array, int offset, int count)<br />
        {<br />
            count = base.Read(array, offset, count);<br />
            this._readCRC = CalculateCRC(this._readCRC, array, offset, count);<br />
            return count;<br />
        }<br />
<br />
        public override void Write(byte[] array, int offset, int count)<br />
        {<br />
            base.Write(array, offset, count);<br />
<br />
            this._writeCRC = CalculateCRC(this._writeCRC, array, offset, count);<br />
        }<br />
    }<br />
<br />

AnswerRe: Adapted Version Pin
Rei Miyasaka31-Mar-06 6:49
Rei Miyasaka31-Mar-06 6:49 
GeneralFantastic! Pin
Emma Burrows15-Mar-06 23:57
Emma Burrows15-Mar-06 23:57 
GeneralRe: Fantastic! Pin
Rei Miyasaka16-Mar-06 0:00
Rei Miyasaka16-Mar-06 0:00 
Questionchecksum? Pin
Christoph Ruegg8-Oct-05 13:39
Christoph Ruegg8-Oct-05 13:39 
AnswerYep, checksum Pin
Rei Miyasaka8-Oct-05 14:11
Rei Miyasaka8-Oct-05 14:11 
GeneralRe: Yep, checksum Pin
Christoph Ruegg8-Oct-05 15:01
Christoph Ruegg8-Oct-05 15:01 
GeneralRe: Yep, checksum Pin
Rei Miyasaka9-Oct-05 21:02
Rei Miyasaka9-Oct-05 21:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.