1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <stdint.h> #include <stdbool.h>
static void generate_crc32_table(uint32_t *table, uint32_t polynomial, bool reflect) { for (uint32_t i = 0; i < 256; i++) { uint32_t crc = reflect ? i : (i << 24); for (int j = 0; j < 8; j++) { if (reflect) { crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0); } else { crc = (crc << 1) ^ ((crc & 0x80000000) ? polynomial : 0); } } table[i] = crc; } }
uint32_t crc32_generic(const uint8_t *data, size_t length, uint32_t polynomial, uint32_t initial, bool input_reflect, bool output_reflect, uint32_t final_xor) { static uint32_t table[256]; static uint32_t last_poly = 0; static bool last_reflect = false; if (polynomial != last_poly || input_reflect != last_reflect) { generate_crc32_table(table, polynomial, input_reflect); last_poly = polynomial; last_reflect = input_reflect; } uint32_t crc = initial; for (size_t i = 0; i < length; i++) { uint8_t byte = data[i]; if (input_reflect) { byte = (byte & 0x55) << 1 | (byte & 0xAA) >> 1; byte = (byte & 0x33) << 2 | (byte & 0xCC) >> 2; byte = (byte & 0x0F) << 4 | (byte & 0xF0) >> 4; } if (input_reflect) { crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; } else { crc = (crc << 8) ^ table[((crc >> 24) ^ byte) & 0xFF]; } } if (output_reflect) { crc = (crc & 0x55555555) << 1 | (crc & 0xAAAAAAAA) >> 1; crc = (crc & 0x33333333) << 2 | (crc & 0xCCCCCCCC) >> 2; crc = (crc & 0x0F0F0F0F) << 4 | (crc & 0xF0F0F0F0) >> 4; crc = (crc & 0x00FF00FF) << 8 | (crc & 0xFF00FF00) >> 8; crc = (crc << 16) | (crc >> 16); } return crc ^ final_xor; }
|