Home

Awesome

Optimized CRC32 library for Arduino

Build Status

This is a target independent, flash and RAM size optimized CRC32 library for Arduino without CRC tables.

CRC32

Library features

Hardware

This library can be used on any 8 or 32-bit target and is optimized for small flash/RAM footprints without CRC table allocations in RAM.

Examples and benchmarks

Arduino IDE | Examples | Erriez CRC32:

Benchmark results on buffers

The benchmark results below may be different for each target and run. Lower duration means faster CRC calculation.

BoardF_CPU4 Bytes64 Bytes512 Bytes1024 Bytes
Arduino UNO (ATMega328)16MHz80us1172us9000us17112us
ESP8266 (WeMOS D1 R2)160MHz3us35us279us557us
ESP32 (WeMOS Lolin32)80MHz2us15us111us223us
DUE (SAM3X8E ARM Cortex-M3)84MHz6us70us547us1103us

Benchmarks performed with the following versions:

Unit tests

This library contains extensive unit tests on a various number of buffer types and lengths:

Library documentation

Usage

Introduction

The library consists of four C-functions for CRC calculation:

// Calculate CRC32 on null-terminated character array (string)
uint32_t crc32String(const char *buffer);
// Calculate CRC32 on one single buffer
uint32_t crc32Buffer(const void *buffer, size_t bufferLength);

// Calculate CRC32 on multiple buffers
// First crc32Update() call should start with argument crc = CRC32_INITIAL
// Next crc32Update() calls should set argument crc = previousCRC
uint32_t crc32Update(const void *buffer, size_t bufferLength, uint32_t crc);
// Call crc32Update() at the end after the last crc32Update()
uint32_t crc32Final(uint32_t crc);

Initialization

Only an include file is required. No object allocation or library initialization required.

#include <ErriezCRC32.h>

Calculate CRC32 on Arduino String

String msg = "Hello world String!";
uint32_t crc = crc32String(msg.c_str());

Calculate CRC32 on null-terminated character array

char msg[] = "Hello world char array!";
uint32_t crc = crc32String(msg);

Calculate CRC32 on single character buffer

char msg[] = "Hello world single buffer!";
uint32_t crc = crc32Buffer(msg, strlen(msg));

Calculate CRC32 on multiple characters

uint32_t crc;

crc = crc32Update("Hello ", 6, CRC32_INITIAL);
crc = crc32Update("world ", 6, crc);
crc = crc32Update("multiple ", 9, crc);
crc = crc32Update("buffers!", 8, crc);
crc = crc32Final(crc);

Calculate CRC32 on multiple buffers

const uint8_t testBuffer1[3] = { 0xEB, 0xE5, 0x51 };
const uint8_t testBuffer2[5] = { 0x87, 0x7F, 0xB8, 0x18, 0x4E };
uint32_t crc;

crc = crc32Update(testBuffer1, sizeof(testBuffer1), CRC32_INITIAL);
crc = crc32Update(testBuffer2, sizeof(testBuffer2), crc);
crc = crc32Final(crc);

Check CRC

void checkCRC(uint32_t crcCalculated, uint32_t crcExpected)
{
    printCRC(crcCalculated);
    Serial.print(F("..."));

    if (crcCalculated == crcExpected) {
        Serial.println(F("OK"));
    } else {
        Serial.print(F("FAILED! Expected: "));
        printCRC(crcExpected);
        Serial.println(F(""));
    }
}

Print 32-bit CRC value

Printing a uint32_t value is not implemented on some targets which is a limitation of Serial.print() or sprintf(). This is a workaround to print a 32-bit hex value:

void printCRC(uint32_t crc)
{
	Serial.print("0x");
    for (int8_t i = 3; i >= 0; i--) {
        uint8_t c = crc >> (i * 8);
        if (c < 0x10) {
            Serial.print("0");
        }
        Serial.print(c, HEX);
    }
}

CRC-calculation with Python

>>> import binascii
>>> hex(binascii.crc32(b'Hello world String!') & 0xffffffff)
'0x55df869b'

Library dependencies

Library installation

Please refer to the Wiki page.

Other Arduino Libraries and Sketches from Erriez