simple CRC32 code

Does anyone have a crc32 implementation they could share that does not use tables?

I have been searching all over the net, and ive tried to adopt the few examples ive found but unfortunately I dont understand the concept well enough for that to be successful ! lol

// ----------------------------- crc32b --------------------------------

/* This is the basic CRC-32 calculation with some optimization but no
table lookup. The the byte reversal is avoided by shifting the crc reg
right instead of left and by using a reversed 32-bit word to represent
the polynomial.
   When compiled to Cyclops with GCC, this function executes in 8 + 72n
instructions, where n is the number of bytes in the input message. It
should be doable in 4 + 61n instructions.
   If the inner loop is strung out (approx. 5*8 = 40 instructions),
it would take about 6 + 46n instructions. */

unsigned int crc32b(unsigned char *message) {
   int i, j;
   unsigned int byte, crc, mask;

   i = 0;
   crc = 0xFFFFFFFF;
   while (message[i] != 0) {
      byte = message[i];            // Get next byte.
      crc = crc ^ byte;
      for (j = 7; j >= 0; j--) {    // Do eight times.
         mask = -(crc & 1);
         crc = (crc >> 1) ^ (0xEDB88320 & mask);
      }
      i = i + 1;
   }
   return ~crc;
}

Why don't you want to use a table?

If you change your mind, this looks good: http://forum.arduino.cc/index.php?topic=91179.0

John, that link is mangled. Try this: http://forum.arduino.cc/index.php?topic=91179.0

Pete

First I have to say thanks! I managed to get the code working!

Originally I wanted a simple routine that was highly portable, and i didnt want to deal with tables , KISS principle, Im ok that it takes a little longer to calculate :slight_smile:

I had to change a few thing but now it works !!!!

Thanks again!

unsigned char test[] = {"HELLO"};


void setup() {
  // put your setup code here, to run once:
  Serial.begin(19200);

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(crc32b(test),HEX);
  delay(1000);

}




// ----------------------------- crc32b --------------------------------

/* This is the basic CRC-32 calculation with some optimization but no
table lookup. The the byte reversal is avoided by shifting the crc reg
right instead of left and by using a reversed 32-bit word to represent
the polynomial.
   When compiled to Cyclops with GCC, this function executes in 8 + 72n
instructions, where n is the number of bytes in the input message. It
should be doable in 4 + 61n instructions.
   If the inner loop is strung out (approx. 5*8 = 40 instructions),
it would take about 6 + 46n instructions. */

unsigned long crc32b(unsigned char *message) {
   int i, j;
   unsigned long Byte, crc, mask;

   i = 0;
   crc = 0xFFFFFFFF;
   while (message[i] != 0) {
      Byte = message[i];            // Get next byte.
      Serial.println(message[i],HEX);
      crc = crc ^ Byte;
      for (j = 7; j >= 0; j--) {    // Do eight times.
         mask = -(crc & 1);
         crc = (crc >> 1) ^ (0xEDB88320 & mask);
      }
      i = i + 1;
   }
   return ~crc;
}

Here is the python3 code to check it

import binascii
#print(binascii.crc32(b"hello world"),)
crc = binascii.crc32(b"HELLO") & 0xffffffff
print('crc32 = {:#010x}'.format(crc))

Firstly, thanks for the code!

I've tried to modify it for numerical data, which can contain a zero, but it has to be tested.

unsigned long crc32c ( unsigned char *message, int bytes )
{
  // CRC-32 Calculation - No Table Lookup - by Billhowl
  // https://forum.arduino.cc/index.php?topic=342371.0
  // Modified for Numerical Data by Specifying Length in Bytes

  // Usage:
  // unsigned char test[6] = {"HELLO"};
  // int bytes = 6;
  // Serial.println ( crc32b ( test, bytes ), HEX);

  unsigned long Byte, mask;
  unsigned long crc = 0xFFFFFFFF;
  int index, shift;

  for ( index = 0 ; index < bytes ; index++ )
  {
    // Get Next Byte
    Byte = message[index];
    Serial.println( message[index], HEX );
    
    // XOR with Next Byte
    crc = crc ^ Byte;

    // Shift 
    for (shift = 7; shift >= 0; shift--)
    {
      mask = -(crc & 1);
      crc = (crc >> 1) ^ (0xEDB88320 & mask);
    }
  }
  return ~crc;
}