-1

I need to convert this CRC32 algorithm to python (using 3.3), but I am a python noob. I tried the built in binascii.crc32(), but the CRC was incorrect. Apparently, STMicro does the CRC32 a bit different. I found an algorithm that works, now I just need it to be in python.

//****************************************************************************

DWORD Crc32Fast(DWORD Crc, DWORD Data)
{
  static const DWORD CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial
    0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
    0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };

  Crc = Crc ^ Data; // Apply all 32-bits

  // Process 32-bits, 4 at a time, or 8 rounds

  Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; //  0x04C11DB7 Polynomial used in STM32
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];
  Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

  return(Crc);
}

//****************************************************************************

DWORD Crc32FastBlock(DWORD Crc, DWORD Size, DWORD *Buffer) // 32-bit units
{
  while(Size--)
    Crc = Crc32Fast(Crc, *Buffer++);

  return(Crc);
}

1 Answers1

3

If my understanding is not mistaken, this should be the code that you want:

CRC_TABLE = (0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
             0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
             0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
             0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD)


def dword(value):
    return value & 0xFFFFFFFF


def crc32_fast(crc, data):
    crc, data = dword(crc), dword(data)
    crc ^= data
    for _ in range(8):
        crc = dword(crc << 4) ^ CRC_TABLE[crc >> 28]
    return crc


def crc32_fast_block(crc, buffer):
    for data in buffer:
        crc = crc32_fast(crc, data)
    return crc


def crc32_fast_bytes(crc, bytes_data, byteorder='big'):
    if len(bytes_data) & 3:
        raise ValueError('bytes_data length must be multiple of four')
    for index in range(0, len(bytes_data), 4):
        data = int.from_bytes(bytes_data[index:index+4], byteorder)
        crc = crc32_fast(crc, data)
    return crc

The function crc32_fast_block expects an initial crc value and an iterable of numbers to run the algorithm on. crc32_fast_bytes is almost the same but expects a bytes value with a length being a multiple of four.

Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117