tools: add crc implementation

Add crc implementation, copied from the internal portable source,
adjusted to be c++ where relevant (e.g. using a vector, etc).

Change-Id: I0998342f4ec8843ba27bf554c2318ca9882e4f7a
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/crc.cpp b/tools/crc.cpp
new file mode 100644
index 0000000..4ed307b
--- /dev/null
+++ b/tools/crc.cpp
@@ -0,0 +1,39 @@
+#include "crc.hpp"
+
+/*
+ * This implementation tracks the specification given at
+ * http://srecord.sourceforge.net/crc16-ccitt.html
+ * Code copied from internal portable sources.
+ */
+std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
+{
+    const std::uint16_t kPoly = 0x1021;
+    const std::uint16_t kLeftBit = 0x8000;
+    const int kExtraRounds = 2;
+    const std::uint8_t* bytes = data.data();
+    std::uint16_t crc = 0xFFFF;
+    size_t i;
+    size_t j;
+    size_t size = data.size();
+
+    for (i = 0; i < size + kExtraRounds; ++i)
+    {
+        for (j = 0; j < 8; ++j)
+        {
+            bool xor_flag = (crc & kLeftBit) ? 1 : 0;
+            crc <<= 1;
+            // If this isn't an extra round and the current byte's j'th bit from
+            // the left is set, increment the CRC.
+            if (i < size && (bytes[i] & (1 << (7 - j))))
+            {
+                crc++;
+            }
+            if (xor_flag)
+            {
+                crc ^= kPoly;
+            }
+        }
+    }
+
+    return crc;
+}