Patrick Venture | 9b750aa | 2018-12-12 14:26:18 -0800 | [diff] [blame] | 1 | #include "crc.hpp" |
| 2 | |
| 3 | /* |
| 4 | * This implementation tracks the specification given at |
| 5 | * http://srecord.sourceforge.net/crc16-ccitt.html |
| 6 | * Code copied from internal portable sources. |
| 7 | */ |
| 8 | std::uint16_t generateCrc(const std::vector<std::uint8_t>& data) |
| 9 | { |
| 10 | const std::uint16_t kPoly = 0x1021; |
| 11 | const std::uint16_t kLeftBit = 0x8000; |
| 12 | const int kExtraRounds = 2; |
| 13 | const std::uint8_t* bytes = data.data(); |
| 14 | std::uint16_t crc = 0xFFFF; |
| 15 | size_t i; |
| 16 | size_t j; |
| 17 | size_t size = data.size(); |
| 18 | |
| 19 | for (i = 0; i < size + kExtraRounds; ++i) |
| 20 | { |
| 21 | for (j = 0; j < 8; ++j) |
| 22 | { |
| 23 | bool xor_flag = (crc & kLeftBit) ? 1 : 0; |
| 24 | crc <<= 1; |
| 25 | // If this isn't an extra round and the current byte's j'th bit from |
| 26 | // the left is set, increment the CRC. |
| 27 | if (i < size && (bytes[i] & (1 << (7 - j)))) |
| 28 | { |
| 29 | crc++; |
| 30 | } |
| 31 | if (xor_flag) |
| 32 | { |
| 33 | crc ^= kPoly; |
| 34 | } |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | return crc; |
| 39 | } |