b1c3ec3af4
- Protocol definition with 6-byte header (chunk_idx: 2B, payload: N B, crc32: 4B) - Node.js server with chunk-based HTTP delivery - C client library with resumable download support - CRC32 implementation (IEEE 802.3) - Test suites for both server and CRC32 - 1024B default chunk size (0.59% overhead)
78 lines
1.8 KiB
C
78 lines
1.8 KiB
C
/**
|
|
* @file crc32.c
|
|
* @brief CRC32 Implementation (IEEE 802.3)
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
|
|
/* 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 */
|
|
}
|