blob: b16eb940f51d275b325d3bdf74d84282916678aa [file] [log] [blame]
Brian Silverman1662a0e2013-12-19 17:50:01 -08001#include "bbb/crc.h"
Brian Silverman8cbf8332013-12-11 13:59:42 -08002
3#include "aos/common/once.h"
4
5// There are various implementations that look a lot like this scattered around
6// the internet.
7
8namespace cape {
9namespace {
10
11const uint32_t kPolynomial = 0x04c11db7;
12
13const uint32_t *GenerateTable() {
14 static uint32_t table[256];
15
16 for (int i = 0; i < 256; ++i) {
17 uint32_t c = i << 24;
18 for (int j = 8; j > 0; --j) {
19 c = c & 0x80000000 ? ((c << 1) ^ kPolynomial) : (c << 1);
20 }
21 table[i] = c;
22 }
23
24 return table;
25}
26
27} // namespace
28
29uint32_t CalculateChecksum(uint8_t *data, size_t length) {
Daniel Petti059be422013-12-14 19:47:42 -080030 static ::aos::Once<const uint32_t> table_once(GenerateTable);
Brian Silverman8cbf8332013-12-11 13:59:42 -080031 const uint32_t *const table = table_once.Get();
32
33 uint32_t r = 0xFFFFFFFF;
34
Brian Silverman53f29182013-12-21 15:16:27 -080035 for (size_t i = 0; i < (length / 4); ++i) {
36 for (int ii = 3; ii >= 0; --ii) {
37 r = (r << 8) ^ table[(r >> 24) ^ data[i * 4 + ii]];
38 }
Brian Silverman8cbf8332013-12-11 13:59:42 -080039 }
40
Brian Silverman53f29182013-12-21 15:16:27 -080041 return r;
Brian Silverman8cbf8332013-12-11 13:59:42 -080042}
43
44} // namespace cape