I have already done a CRC16 calculation algorithm, and it works very well. Now, as a next step, I am trying to write a CRC16 algorithm using a lookup table.
First of all, I create a dummy message with some random values, pass it to the algorithm with its length, and the result is stored into a variable named crc
.
Then, I add the crc
into my data at the end of the array, and I pass it to the algorithm in order to calculate a new crc (crc_2
).
I expected that crc_2
was equal to zero, but every time its value is different from that.
These are the data:
uint16_t crc16_tab[256] =
{
0x0000, 0xA001, 0xE003, 0x4002, 0x6007, 0xC006, 0x8004, 0x2005, 0xC00E, 0x600F, 0x200D, 0x800C, 0xA009, 0x0008, 0x400A, 0xE00B,
0x201D, 0x801C, 0xC01E, 0x601F, 0x401A, 0xE01B, 0xA019, 0x0018, 0xE013, 0x4012, 0x0010, 0xA011, 0x8014, 0x2015, 0x6017, 0xC016,
0x403A, 0xE03B, 0xA039, 0x0038, 0x203D, 0x803C, 0xC03E, 0x603F, 0x8034, 0x2035, 0x6037, 0xC036, 0xE033, 0x4032, 0x0030, 0xA031,
0x6027, 0xC026, 0x8024, 0x2025, 0x0020, 0xA021, 0xE023, 0x4022, 0xA029, 0x0028, 0x402A, 0xE02B, 0xC02E, 0x602F, 0x202D, 0x802C,
0x8074, 0x2075, 0x6077, 0xC076, 0xE073, 0x4072, 0x0070, 0xA071, 0x407A, 0xE07B, 0xA079, 0x0078, 0x207D, 0x807C, 0xC07E, 0x607F,
0xA069, 0x0068, 0x406A, 0xE06B, 0xC06E, 0x606F, 0x206D, 0x806C, 0x6067, 0xC066, 0x8064, 0x2065, 0x0060, 0xA061, 0xE063, 0x4062,
0xC04E, 0x604F, 0x204D, 0x804C, 0xA049, 0x0048, 0x404A, 0xE04B, 0x0040, 0xA041, 0xE043, 0x4042, 0x6047, 0xC046, 0x8044, 0x2045,
0xE053, 0x4052, 0x0050, 0xA051, 0x8054, 0x2055, 0x6057, 0xC056, 0x205D, 0x805C, 0xC05E, 0x605F, 0x405A, 0xE05B, 0xA059, 0x0058,
0xA0E9, 0x00E8, 0x40EA, 0xE0EB, 0xC0EE, 0x60EF, 0x20ED, 0x80EC, 0x60E7, 0xC0E6, 0x80E4, 0x20E5, 0x00E0, 0xA0E1, 0xE0E3, 0x40E2,
0x80F4, 0x20F5, 0x60F7, 0xC0F6, 0xE0F3, 0x40F2, 0x00F0, 0xA0F1, 0x40FA, 0xE0FB, 0xA0F9, 0x00F8, 0x20FD, 0x80FC, 0xC0FE, 0x60FF,
0xE0D3, 0x40D2, 0x00D0, 0xA0D1, 0x80D4, 0x20D5, 0x60D7, 0xC0D6, 0x20DD, 0x80DC, 0xC0DE, 0x60DF, 0x40DA, 0xE0DB, 0xA0D9, 0x00D8,
0xC0CE, 0x60CF, 0x20CD, 0x80CC, 0xA0C9, 0x00C8, 0x40CA, 0xE0CB, 0x00C0, 0xA0C1, 0xE0C3, 0x40C2, 0x60C7, 0xC0C6, 0x80C4, 0x20C5,
0x209D, 0x809C, 0xC09E, 0x609F, 0x409A, 0xE09B, 0xA099, 0x0098, 0xE093, 0x4092, 0x0090, 0xA091, 0x8094, 0x2095, 0x6097, 0xC096,
0x0080, 0xA081, 0xE083, 0x4082, 0x6087, 0xC086, 0x8084, 0x2085, 0xC08E, 0x608F, 0x208D, 0x808C, 0xA089, 0x0088, 0x408A, 0xE08B,
0x60A7, 0xC0A6, 0x80A4, 0x20A5, 0x00A0, 0xA0A1, 0xE0A3, 0x40A2, 0xA0A9, 0x00A8, 0x40AA, 0xE0AB, 0xC0AE, 0x60AF, 0x20AD, 0x80AC,
0x40BA, 0xE0BB, 0xA0B9, 0x00B8, 0x20BD, 0x80BC, 0xC0BE, 0x60BF, 0x80B4, 0x20B5, 0x60B7, 0xC0B6, 0xE0B3, 0x40B2, 0x00B0, 0xA0B1
};
uint16_t fast_crc16(uint16_t crc,uint8_t* buffer, uint32_t len)
{
while (len--)
{
crc = crc16_tab[(crc >> 8) ^ *buffer++] ^ (crc << 8);
}
return (crc);
}
int main() {
/*DUMMY MESSAGE*/
uint8_t data[6] = {0x10,0x20, 0X30,0X40,0,0};
uint16_t crc = 0;
uint16_t crc_2 = 0;
/*FIRST CRC*/
crc = fast_crc16(0XFFFF,data, 4);
/*COPY CRC INTO DATA*/
memcpy((void*)&data[4], (void*)&crc_2, 2);
/*SECOND CRC*/
crc_2 = fast_crc16(crc,data, 6);
printf("%x", crc_2);
return 0;
}
First off, you're putting the computed CRC in crc
, but then copy crc_2
to the end of the message, which you set to zero. You want to copy crc
, not crc_2
.
Second, you are using memcpy()
to copy the CRC to the end of the message, which could do one of two different things depending on the endianess of your machine. To make it independent of the endianess of your machine, and to do the right thing, you need to copy the high byte of the CRC to data[4]
, and the low byte to data[5]
:
data[4] = crc >> 8;
data[5] = crc;
Third, your second CRC calculation needs to start with the same initial value of your CRC definition, which is 0xffff
. Not crc
. So:
crc_2 = fast_crc16(0xffff, data, 6);
Then you'll get zero.