blob: d6f59ef310c2a5e22286802caff8d6cd0f608247 [file] [log] [blame]
Patrick Venture9b750aa2018-12-12 14:26:18 -08001#include "crc.hpp"
2
Patrick Venture9b534f02018-12-13 16:10:02 -08003namespace host_tool
4{
5
Patrick Venture9b750aa2018-12-12 14:26:18 -08006/*
7 * This implementation tracks the specification given at
8 * http://srecord.sourceforge.net/crc16-ccitt.html
9 * Code copied from internal portable sources.
10 */
11std::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;
Patrick Venture28abae72018-12-14 09:44:02 -080018 std::size_t i;
19 std::size_t j;
20 std::size_t size = data.size();
Patrick Venture9b750aa2018-12-12 14:26:18 -080021
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}
Patrick Venture9b534f02018-12-13 16:10:02 -080043
44} // namespace host_tool