You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.6 KiB
66 lines
1.6 KiB
// crc32.c - CRC32 checksum implementation |
|
#include "crc32.h" |
|
#include <string.h> |
|
|
|
static uint32_t crc32_table[256]; |
|
static int crc32_table_initialized = 0; |
|
|
|
static void init_crc32_table(void) { |
|
if (crc32_table_initialized) 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) ^ 0xEDB88320; |
|
} else { |
|
crc >>= 1; |
|
} |
|
} |
|
crc32_table[i] = crc; |
|
} |
|
|
|
crc32_table_initialized = 1; |
|
} |
|
|
|
void crc32_init(void) { |
|
init_crc32_table(); |
|
} |
|
|
|
uint32_t crc32_calc(const uint8_t *data, size_t len) { |
|
if (!crc32_table_initialized) { |
|
init_crc32_table(); |
|
} |
|
|
|
if (!data || len == 0) return 0xFFFFFFFF; |
|
|
|
uint32_t crc = 0xFFFFFFFF; |
|
for (size_t i = 0; i < len; i++) { |
|
uint8_t byte = data[i]; |
|
uint32_t table_index = (crc ^ byte) & 0xFF; |
|
crc = (crc >> 8) ^ crc32_table[table_index]; |
|
} |
|
|
|
return ~crc; |
|
} |
|
|
|
uint32_t crc32_calc_ex(const uint8_t *data, size_t len, uint32_t initial_crc) { |
|
if (!crc32_table_initialized) { |
|
init_crc32_table(); |
|
} |
|
|
|
if (!data || len == 0) return initial_crc; |
|
|
|
uint32_t crc = initial_crc; |
|
for (size_t i = 0; i < len; i++) { |
|
uint8_t byte = data[i]; |
|
uint32_t table_index = (crc ^ byte) & 0xFF; |
|
crc = (crc >> 8) ^ crc32_table[table_index]; |
|
} |
|
|
|
return crc; |
|
} |
|
|
|
uint32_t crc32_update(uint32_t crc, const uint8_t *data, size_t len) { |
|
return crc32_calc_ex(data, len, crc); |
|
} |