1
votes

I have referred hackersdelight's CRC32 implementations, I just edited crc32h function from there and made it get a byte and update the last CRC32 Value. Because I need to calculate the new CRC32 value with the new byte input. I can get it work by sending an array to it, by I can not save my whole to to the array before calling the CRC32 function. So I want to update the last CRC32 Value which is calculated for previous byte. Here is the implementation of hackersdelight:

unsigned int crc32h(unsigned char *message) {
   int i, crc;
   unsigned int byte, c;
   const unsigned int g0 = 0xEDB88320,    g1 = g0>>1,
      g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5,
      g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1;

   i = 0;
   crc = 0xFFFFFFFF;
   while ((byte = message[i]) != 0) {    // Get next byte.
      crc = crc ^ byte;
      c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^
          ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^
          ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^
          ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0);
      crc = ((unsigned)crc >> 8) ^ c;
      i = i + 1;
   }
   return ~crc;
}

Below is the function edited by me.

unsigned int crc32h(uint8_t byte,int crc) {

   unsigned int c;
   const unsigned int g0 = 0xEDB88320,    g1 = g0>>1,
      g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5,
      g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1;


   crc = crc ^ byte;
   c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^
   ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^
   ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^
   ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0);
   crc = ((unsigned)crc >> 8) ^ c;

   crc = ~crc;

   return crc;
}

This code calculates the CRC32 Value successfully if I send a byte and the default CRC value (0xFFFFFFFF). But I can not Update the CRC, for example:

int crc = 0xFFFFFFFF;

crc = crc32h(0x11,crc);  //This gives me the correct CRC32 for `0x11`

crc = crc32h(0x22,crc);  //But this does not give me the correct CRC32 for `0x1122`

Why it does not update the new CRC Value regarding to previous CRC Value?

1
I think if you make the call crc = crc32h(0x22, ~crc), it'll do what you want.Jim Mischel
@JimMischel That also worked, but again it is needed to start with 0 instead of 0xFFFFFFFF.abdullah cinar
Yeah, I made that comment and was getting around to writing an answer when Martin posted his.Jim Mischel

1 Answers

3
votes

The difference is that the first function inverts the CRC only once, after digesting all bytes, whereas your edited function inverts the CRC after processing each single byte.

A possible solution could be to invert the CRC also when the function is entered:

unsigned int crc32h(uint8_t byte,int crc) {

    unsigned int c;
    const unsigned int g0 = 0xEDB88320,    g1 = g0>>1,
    g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5,
    g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1;

    crc = ~crc; // <--- ADDED
    crc = crc ^ byte;
    c = ((crc<<31>>31) & g7) ^ ((crc<<30>>31) & g6) ^
    ((crc<<29>>31) & g5) ^ ((crc<<28>>31) & g4) ^
    ((crc<<27>>31) & g3) ^ ((crc<<26>>31) & g2) ^
    ((crc<<25>>31) & g1) ^ ((crc<<24>>31) & g0);
    crc = ((unsigned)crc >> 8) ^ c;
    crc = ~crc;

    return crc;
}

and start with 0x0 instead of 0xFFFFFFFF:

int crc = 0;
crc = crc32h(0x11,crc);
crc = crc32h(0x22,crc);