I'm using right now zlib.crc32, but for C there is no such library
Um, yes, there is. It's called zlib. zlib is written in C, and it's what Python is using! Hence the name of the class.
You can use the crc32()
function in zlib. That implementation is a fair bit faster than others you might find. Read zlib.h for the interface information.
You can compile zlib yourself, or it may already be installed on your system.
Update:
I now see your comment (which should be edited into the question since it is critical to getting the right answer) that you have extremely limited memory. Then you can use this:
static uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len)
{
int k;
crc = ~crc;
while (len--) {
crc ^= *buf++;
for (k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
}
return ~crc;
}
The crc is initially set to zero.
The use of ~
will give the correct result, since the uint32_t
type in stdint.h
is assured to be 32 bits.
If you can afford a little more code space, then unrolling the loop will likely speed it up (if the compiler doesn't already do this):
static uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len)
{
crc = ~crc;
while (len--) {
crc ^= *buf++;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
crc = crc & 1 ? (crc >> 1) ^ 0xedb88320 : crc >> 1;
}
return ~crc;
}
You said that you only have 4 KBytes of "memory". Is that just working memory for the program, or does the program have to live there as well? If you have more space in flash for example for the code, then the table can be precomputed and stored with the code. A table-driven CRC will be much faster. The zlib code provides table-driven CRCs that do one byte at a time and four-bytes at a time, requiring respectively a 1Kbyte or 4Kbyte table.
Update 2:
Since you answered in a comment that the 4KBytes are just working memory, then you should use a table-driven CRC. You can simply use the crc32()
function in zlib's crc32.c
and the table in crc32.h
with BYFOUR
undefined.