Created
July 6, 2014 16:36
-
-
Save aurelj/270bb8af82f65fa645c1 to your computer and use it in GitHub Desktop.
Simple CRC-16-MCRF4XX C implementation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stddef.h> | |
uint16_t crc16_mcrf4xx(uint16_t crc, uint8_t *data, size_t len) | |
{ | |
if (!data || len < 0) | |
return crc; | |
while (len--) { | |
crc ^= *data++; | |
for (int i=0; i<8; i++) { | |
if (crc & 1) crc = (crc >> 1) ^ 0x8408; | |
else crc = (crc >> 1); | |
} | |
} | |
return crc; | |
} |
Consider this instead of your 8-bit loop:
#include <stdint.h> #include <stddef.h> uint16_t crc16_mcrf4xx(uint16_t crc, uint8_t *data, size_t len) { uint8_t t; uint8_t L; if (!data || len < 0)
Should not this be if (!data || len <= 0). I am not sure if should calculate CRC if length passed == 0;
return crc; while (len--) { crc ^= *data++; L = crc ^ (crc << 4); t = (L << 3) | (L >> 5); L ^= (t & 0x07); t = (t & 0xF8) ^ (((t << 1) | (t >> 7)) & 0x0F) ^ (uint8_t)(crc >> 8); crc = (L << 8) | t; } return crc;
}
You're right, it should be if (!data || len <= 0)
for performance, but the functionality comes out the same because len--
returns 0 so it skips down to return crc;
anyways. The CRC of an empty array is valid and should equal the CRC start value.
With just -O1
there is not much difference. Tested with 12 bytes:
$ g++ -O0 crc.cpp -o crc
$ ./crc
10M runs crc16_mcrf4xx: 945.964 ms
10M runs crc16_mcrf4xx_fast: 509.515 ms
$ g++ -O1 crc.cpp -o crc
$ ./crc
10M runs crc16_mcrf4xx: 12.783 ms
10M runs crc16_mcrf4xx_fast: 12.746 ms
1024 bytes:
$ g++ -O0 crc.cpp -o crc
$ ./crc
10k runs crc16_mcrf4xx: 352.066 ms
10k runs crc16_mcrf4xx_fast: 73.724 ms
$ g++ -O1 crc.cpp -o crc
$ ./crc
10k runs crc16_mcrf4xx: 0.016 ms
10k runs crc16_mcrf4xx_fast: 0.015 ms
The initial implementation and the one by @mudgek1 produce different results for some numbers (e.g. 0x76). Which one is correct?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
mudgek1 works great! Thanks