|
//=========================================================================
// Calculates the CRC for a given buffer.
//
// Example calculate the CRC for a GUID:
// GUID g;
// CoCreateGuid( &g );
// crc = crc32( (unsigned char*)&g, sizeof( GUID ) );
// or
// crc = crc16( (unsigned char*)&g, sizeof( GUID ) );
//
//=========================================================================
//=========================================================================
// CRC32 stuff.
//=========================================================================
//-------------------------------------------------------------------------
// Build auxiliary table for parallel byte-at-a-time CRC-32.
//-------------------------------------------------------------------------
#define CRC32_POLY 0x04c11db7 // AUTODIN II, Ethernet, & FDDI
inline long* getCrc32Table()
{
static long crc32Table[256];
return crc32Table;
}
//-------------------------------------------------------------------------
// Initialized first time "crc32()" is called. If you prefer, you can
// statically initialize it at compile time. [Another exercise.]
//-------------------------------------------------------------------------
inline void InitCRC32()
{
int i, j;
unsigned long c;
for (i = 0; i < 256; ++i)
{
for (c = i << 24, j = 8; j > 0; --j)
c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
getCrc32Table()[i] = c;
}
}
inline unsigned long crc32( unsigned char *buf, int len)
{
unsigned char *p;
unsigned long crc;
// if not already done, build table
if (!getCrc32Table()[1])
InitCRC32();
// preload shift register, per CRC-32 spec
crc = 0xffffffff;
for ( p = buf; len > 0; ++p, --len )
crc = ( crc << 8 ) ^ getCrc32Table()[( crc >> 24 ) ^ *p];
// transmit complement, per CRC-32 spec
return ~crc;
}
//=========================================================================
// CRC16 stuff.
//=========================================================================
inline unsigned short* getCrc16Table()
{
static unsigned short crc16Table[256];
return crc16Table;
}
inline void InitCRC16(void)
{
int i, j;
unsigned short k;
for (i = 0; i < 256; i++)
{
k = 0xC0C1;
for (j = 1; j < 256; j <<= 1)
{
if (i & j)
getCrc16Table()[i] ^= k;
k = (unsigned short)( (k << (short)1) ^ 0x4003 );
}
}
}
inline unsigned short crc16( unsigned char *buf, unsigned nbytes )
{
unsigned char *p;
unsigned char *lim;
unsigned short crc = 0;
// if not already done, build table
if (!getCrc16Table()[1])
InitCRC16();
p = buf;
lim = p + nbytes;
while (p < lim)
crc = (unsigned short) ( (crc >> (short)8 ) ^ getCrc16Table()[(crc & 0xFF) ^ *p++] );
return crc;
}
|
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.
My interests mostly revolve around making machines do work for people. I'm a computer programmer, software architect, development manager, program manager and a computer programmer. I said programmer twice because I believe you need to be able to do the work yourself if you're going to direct others. I started my career creating software for abstract art, followed by work in embedded systems and HMI. In the 90s I created a successful product called Visual DLL and helped develop the Sales Force Automation product, Arsenal. I've often been involved in online communities, creating games, utilities, and collaboration software. I'm passionate about agile requirements management, acceptance testing through executable specification, and anything that will make developers more productive. My current role is Principal Scientist where I get to work on different technologies with an awesome team, to solve real-world practical problems. I'm Armenian, so talking is in my nature -- if you see me online or offline, say hi and we'll geek out about the latest tools and libraries. If you learned something cool recently (and you should if you're a lifelong learner), then I'd like to hear about it.