# CRC32

```c
#define FIO_CRC32
#include "fio-stl.h"
```

Fast CRC32 using the ITU-T V.42 / ISO 3309 / gzip polynomial (`0xEDB88320`). Useful for gzip, PNG, and anything else that expects this particular CRC32 flavor.

The implementation picks the best available path at compile time:

- ARM aarch64 with the CRC32 extension uses scalar CRC32 instructions, with a PMULL bulk-fold path when the crypto / PMULL feature is available.
- x86 / x64 with SSE4.2 and PCLMULQDQ uses a PCLMULQDQ bulk path and the software tail path.
- Other builds use the always-present slicing-by-16 software fallback.

**Note:** this is **not** CRC32-C (Castagnoli, polynomial `0x82F63B78`). The ARM scalar path uses the gzip-polynomial CRC32 instructions (`__crc32b`, `__crc32w`, `__crc32d`), not the Castagnoli variants.

### API Functions

#### `fio_crc32`

```c
SFUNC uint32_t fio_crc32(const void *data, size_t len, uint32_t initial_crc);
```

Computes the CRC32 of `len` bytes at `data`. Pass `0` for `initial_crc` to start fresh, or pass a previous result to continue an incremental checksum across multiple buffers.

**Returns:** the CRC32 checksum.

### Example — single buffer

```c
#define FIO_CRC32
#include "fio-stl.h"

int main(void) {
  const char *msg = "Hello, World!";
  uint32_t crc = fio_crc32(msg, strlen(msg), 0);
  printf("CRC32: 0x%08X\n", crc);
  return 0;
}
```

### Example — incremental

```c
uint32_t crc = 0;
crc = fio_crc32("Hello, ", 7, crc);
crc = fio_crc32("World!", 6, crc);
/* crc matches a single call over "Hello, World!" */
```

------------------------------------------------------------
