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