commit
531b2e8f52
2 changed files with 126 additions and 0 deletions
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
CC=gcc
|
||||
OBJ=crc.o
|
||||
CFLAGS=-Wall -Wextra -Werror -pedantic
|
||||
|
||||
%.o: %.c $(DEPS) |
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
crc: $(OBJ) |
||||
$(CC) -o $@ $^ $(CFLAGS)
|
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* crc.c - reference CRC implementations and LUT generator |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdint.h> |
||||
|
||||
/*
|
||||
* CRC-16-IBM -- reversed reciprocal representation |
||||
* https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Polynomial_representations_of_cyclic_redundancy_checks
|
||||
*/ |
||||
#define CRCPOLY (0xc002) |
||||
|
||||
static uint16_t crc16_lut[256] = { 0x0000 }; |
||||
|
||||
uint16_t crc16(uint8_t *data, uint32_t len); |
||||
void crc16_gen(); |
||||
uint16_t crc16_ref(uint8_t *Pkt, uint32_t PktCnt); |
||||
|
||||
int main() |
||||
{ |
||||
uint8_t i; |
||||
uint8_t golden_packet[32] = {
|
||||
0xf2, 0x22, 0x22, 0x22, |
||||
0x20, 0x00, 0x00, 0x00,
|
||||
0x78, 0x56, 0x34, 0x12,
|
||||
0xd2, 0xc3, 0xb4, 0xa5,
|
||||
0x10, 0x00, 0x00, 0x00,
|
||||
0x01, 0x5a, 0x00, 0x00,
|
||||
0x42, 0x43, 0x44, 0x45,
|
||||
0x46, 0x47, 0x00, 0x00 |
||||
}; |
||||
|
||||
/* generate lookup table */ |
||||
crc16_gen(); |
||||
|
||||
/* print out the table (for embedding into code data sections) */ |
||||
printf("CRC byte lookup table:\n0x0000"); |
||||
for(i = 0; i < 255; i++) |
||||
{ |
||||
printf(", 0x%04x", crc16_lut[i + 1]); |
||||
} |
||||
printf("\n\n"); |
||||
|
||||
/* compute the golden checksum using the LUT and a reference algorithm */ |
||||
printf("Golden Checksum: 0x%04x\n", crc16(golden_packet, 32)); |
||||
printf("Reference Golden Checksum: 0x%04x\n", crc16_ref(golden_packet, 32)); |
||||
|
||||
return(0); |
||||
} |
||||
|
||||
/* fast CRC calculation using LUT */ |
||||
uint16_t crc16(uint8_t *data, uint32_t len) |
||||
{
|
||||
uint32_t i; |
||||
uint16_t rem = 0; |
||||
|
||||
for (i = 0; i < len; i++) |
||||
{ |
||||
rem = (rem >> 8) ^ crc16_lut[data[i] ^ (rem & 0xff)]; |
||||
} |
||||
|
||||
return(rem); |
||||
} |
||||
|
||||
/* fast CRC LUT generation */ |
||||
void crc16_gen() |
||||
{ |
||||
uint16_t crc = 1; |
||||
uint8_t i; |
||||
uint16_t j; |
||||
|
||||
for(i = 0x80; i > 0; i >>= 1) |
||||
{ |
||||
if(crc & 1) |
||||
{ |
||||
crc = (crc >> 1) ^ CRCPOLY; |
||||
} |
||||
else |
||||
{ |
||||
crc >>= 1; |
||||
} |
||||
|
||||
for(j = 0; j < 256; j += 2 * i) |
||||
{ |
||||
crc16_lut[i + j] = crc ^ crc16_lut[j]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* reference CRC implementation */ |
||||
uint16_t crc16_ref(uint8_t *buf, uint32_t len) |
||||
{ |
||||
uint16_t rem = 0; |
||||
uint16_t dat; |
||||
uint16_t tmp; |
||||
uint32_t i, j; |
||||
|
||||
for(i = 0; i < len; i++) |
||||
{ |
||||
dat = buf[i]; |
||||
for(j = 0; j < 8; j++) |
||||
{ |
||||
tmp = (rem ^ dat) & 0x0001; |
||||
|
||||
rem >>= 1; |
||||
dat >>= 1; |
||||
|
||||
if(tmp) |
||||
{ |
||||
rem ^= CRCPOLY; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return(rem); |
||||
} |
Loading…
Reference in new issue