/** * @file crc32.c * @brief CRC32 Implementation (IEEE 802.3) */ #include #include #include /* IEEE 802.3 CRC32 polynomial (reversed) */ #define CRC32_POLY 0xEDB88320UL /* CRC32 lookup table (256 entries) */ static uint32_t crc32_table[256]; static bool crc32_table_init = false; /** * Initialize CRC32 lookup table */ static void crc32_init_table(void) { if (crc32_table_init) return; for (uint32_t i = 0; i < 256; i++) { uint32_t crc = i; for (int j = 0; j < 8; j++) { if (crc & 1) { crc = (crc >> 1) ^ CRC32_POLY; } else { crc >>= 1; } } crc32_table[i] = crc; } crc32_table_init = true; } /** * Calculate CRC32 (IEEE 802.3 polynomial) * * @param data Input data * @param len Input length * @return CRC32 value */ uint32_t chunk_crc32(const uint8_t *data, size_t len) { crc32_init_table(); uint32_t crc = 0xFFFFFFFFUL; /* Initial value */ for (size_t i = 0; i < len; i++) { uint8_t index = (crc ^ data[i]) & 0xFF; crc = (crc >> 8) ^ crc32_table[index]; } return crc ^ 0xFFFFFFFFUL; /* Final XOR */ } /** * Update CRC32 with additional data * * @param crc Previous CRC value (already XORed with 0xFFFFFFFF) * @param data New data * @param len Data length * @return Updated CRC value */ uint32_t chunk_crc32_update(uint32_t crc, const uint8_t *data, size_t len) { crc32_init_table(); /* Undo final XOR from previous calculation */ crc ^= 0xFFFFFFFFUL; for (size_t i = 0; i < len; i++) { uint8_t index = (crc ^ data[i]) & 0xFF; crc = (crc >> 8) ^ crc32_table[index]; } return crc ^ 0xFFFFFFFFUL; /* Final XOR */ }