Brian Silverman | 1662a0e | 2013-12-19 17:50:01 -0800 | [diff] [blame] | 1 | #include "bbb/crc.h" |
Brian Silverman | 8cbf833 | 2013-12-11 13:59:42 -0800 | [diff] [blame] | 2 | |
| 3 | #include "aos/common/once.h" |
| 4 | |
| 5 | // There are various implementations that look a lot like this scattered around |
| 6 | // the internet. |
| 7 | |
| 8 | namespace cape { |
| 9 | namespace { |
| 10 | |
| 11 | const uint32_t kPolynomial = 0x04c11db7; |
| 12 | |
| 13 | const 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 | |
| 29 | uint32_t CalculateChecksum(uint8_t *data, size_t length) { |
Daniel Petti | 059be42 | 2013-12-14 19:47:42 -0800 | [diff] [blame] | 30 | static ::aos::Once<const uint32_t> table_once(GenerateTable); |
Brian Silverman | 8cbf833 | 2013-12-11 13:59:42 -0800 | [diff] [blame] | 31 | const uint32_t *const table = table_once.Get(); |
| 32 | |
| 33 | uint32_t r = 0xFFFFFFFF; |
| 34 | |
Brian Silverman | 53f2918 | 2013-12-21 15:16:27 -0800 | [diff] [blame^] | 35 | 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 Silverman | 8cbf833 | 2013-12-11 13:59:42 -0800 | [diff] [blame] | 39 | } |
| 40 | |
Brian Silverman | 53f2918 | 2013-12-21 15:16:27 -0800 | [diff] [blame^] | 41 | return r; |
Brian Silverman | 8cbf833 | 2013-12-11 13:59:42 -0800 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | } // namespace cape |