Click here to Skip to main content
Click here to Skip to main content

Cyclic Redundancy Check (CRC32) HashAlgorithm

By , 4 Oct 2002
 

Sample Image - CRC32_DotNet1.jpg

Sample Image - CRC32_DotNet1.jpg

Caution

As Paul Ravier mentioned, this class should NOT be used for security purposes. The CRC32 algorithm can easily be brute forced in minutes. For security applications use MD5, SHA1, SHA256, SHA384, or SHA512 in the System.Security.Cryptography namespace.

Introduction

The System.Security.Cryptography contains the HashAlgorithm. The HashAlgorithm class represents the base class from which all implementations of cryptographic hash algorithms must derive. Although I don't believe the Cyclic Redundancy Check algorithm is considered a true cryptographic hash algorithm, it does fit into the HashAlgorithm pattern.

The CRC32 algorithm is initialized using a 32-bit unsigned integer. This unsigned integer is known the polynomial. Different polynomials produce different check sums. The polynomial is used to generate a 256 element table that speeds the calculation. Normal applications will use the same polynomial throughout it's life-time. Due to this, the default behavior of the CRC32 class caches the table on first use. This behavior can be changed by setting the AutoCache property to false

Sample Usage

// Generic function using HashAlgorithm 
public void HashData(HashAlgorithm hashAlg, string str )
{
    byte[] rawBytes = System.Text.ASCIIEncoding.ASCII.GetBytes( str );
    byte[] hashData = hashAlg.ComputeHash( rawBytes );
    Console.WriteLine( BitConverter.ToString( hashData ) );
}

// Example showing that both functions can be used
public void Example()
{
    string str = "A lazy brown dog..."; // data to hash

    MD5 md5 = new MD5CryptoServiceProvider();
    HashData( md5, str); // Sample of the MD5 algorithm 

    CRC32 crc = new CRC32(); // equivalent to new CRC32(CRC32.DefaultPolynomial);
    HashData( crc, str); // Compute the default CRC32 value for a string
}

Conclusion

Although the MD5, SHA1, SHA256, SHA384, and SHA512 are more accurate than the CRC32 algorithm, sometimes you do not have a choice due various reasons. This class can be used without modification anywhere other HashAlgorithm classes can.

History

6 Oct 2002 - updated source

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Phil Bolduc
Web Developer
Canada Canada
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberTuilindo1 Nov '10 - 5:07 
Perfect, CRC32 is exactly what I have been looking for! ... for speed up indexes in database (with MD5 indexes).
GeneralCRC32 to StringmemberMPTP2 Aug '09 - 1:19 
Hi,
 
Is there any method to get string from a CRC32 value?
QuestionWhat is the collision probabiltymemberepnetRob23 Sep '08 - 8:38 
What is the probability that any two given strings will result in the same Hash? Thanks.
QuestionEL LoggingmemberOnSeCalme17 Sep '08 - 9:37 
Hi, Phil
 
For the last couple of days, I have been researching the web for guidance on Enterprise Library Logging application block and I found your contribution in Logging on codeproject and codeplex. I downloaded the zip file and I find it very interesting. I will use it as a starting piece for my own implementation of Logging.
I have a few questions if you have a little bit of time. My public email is vancouvercancun at yahoo dot ca. Please contact me there.
Thanks
Steve
GeneralOpen Source CRC32 UtilitysussLiquid Wax1 Sep '04 - 10:08 
Hello everyone!
 
I've created an open source CRC32 utility using C# that will scan folders/directories and generate CRCs for each file (and give you a CRC for the whole set).
 
It's stable and works well. I wish to update it so that CRC numbers are generated on removable media using sectors and not through the file system.
 
http://bloodhoundcrc.sourceforge.net
GeneralFaster, faster!membercookd16 Jul '04 - 19:29 
In my tests, using the following implementation of HashCore makes your Crc32 class about 2.5 times faster.
 
protected override void HashCore(byte[] buffer, int offset, int count)
{
uint crc = m_crc;
for (int i = offset; i < offset + count; i++)
{
crc = (crc >> 8) ^ crc32Table[(crc & 0xFF) ^ buffer[i]];
}
m_crc = crc;
}

 
On my system, the original Crc32 took 10.6s to read a 400MB ISO. This one takes 3.9s.
 
And if you really want speed, you can get it down to 3.6 seconds with a bit of unsafe code:
 
unsafe protected override void HashCore(byte[] buffer, int offset, int count)
{
if (offset < 0 || buffer.Length < offset)
{
throw new ArgumentOutOfRangeException("buffer");
}
if (count < 0 || buffer.Length < offset + count)
{
throw new ArgumentOutOfRangeException("count");
}
 
fixed (byte* pCur = &buffer[offset])
{
fixed (uint* pTable = crc32Table)
{
uint crc = m_crc;
for (int i = 0; i < count; i++)
{
crc = (crc >> 8) ^ pTable[(crc & 0xFF) ^ pCur[i]];
}
m_crc = crc;
}
}
}

 
Note that pointers aren't necessarily any faster by nature. I think the extra speedup comes from not checking the array bounds each time through the loop, which saves about 10%.
 
My benchmarking shows that the unsafe version is now within 10% of the speed of the best native code version I've found. Pretty cool, eh?
GeneralRe: Faster, faster!memberHolgerK22 Jul '05 - 0:04 
I tested your code with 40 and 60 mb files.
The unsafe code is way slower than your safe code version.
But both are faster than the original.
 
But ALL are slower than the .NET MD5 implementation.
 
So at least regarding speed all stuff here is useless.
GeneralRe: Faster, faster!memberMadHatter ¢28 Mar '06 - 19:33 
take a look at the current "managed" hash functions in the framework in reflector.
 
you'll see that all their internal implementations are in an unsafe blocks, so I'd tend to believe there's a real performance gain by using them.
 



/bb|[^b]{2}/
 

GeneralModified + Tested version availablememberSteven Campbell28 Mar '04 - 10:50 
...currently included as part of the source code for my implementation of the yEnc algorithm.
 
http://www.codeproject.com/csharp/yenc.asp
[EDIT: updated link]
 
The version in my article included the following fixes:
* correctly reflected polynomial
* corrected the byte loop so that it supports non-0 offsets
* removed redundant methods
* added a set of NUnit tests
 
Thanks for the code Phil, it worked great after a little tweaking Smile | :)
GeneralRe: Modified + Tested version availablememberPhil Bolduc28 Mar '04 - 20:54 
Great, I am glad it finally worked for you. There have been so many posts regarding how it does not calculate the correct CRC for this or that. (Zip vs Ethernet, etc).
 
A yenc implementation eh? Nice. Perhaps, I'll be able to switch to a C# implmentation of my usenet downloader vs a perl one.
 
Phil

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 5 Oct 2002
Article Copyright 2002 by Phil Bolduc
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid