C++: the Internet checksum
A checksum lets a receiver detect accidental bit errors. The Internet checksum (RFC 1071) adds the data as 16-bit words, folds any carry out of bit 15 back into the low bits, and takes the bitwise complement of the result. A sender stores it in the header.
C++
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>
std::uint16_t checksum(const std::vector<std::uint8_t>& bytes) {
std::uint32_t sum = 0;
for (std::size_t i = 0; i + 1 < bytes.size(); i += 2) {
sum += (bytes[i] << 8) | bytes[i + 1];
}
if (bytes.size() % 2 == 1) {
sum += bytes.back() << 8;
}
while (sum >> 16) {
sum = (sum & 0xFFFF) + (sum >> 16);
}
return static_cast<std::uint16_t>(~sum);
}
void show(const char* label, std::uint16_t value) {
std::cout << label << "0x" << std::hex << std::setw(4) << std::setfill('0') << value << std::dec << "\n";
}
int main() {
std::vector<std::uint8_t> packet = {0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7};
std::uint16_t c = checksum(packet);
show("checksum: ", c);
packet.push_back(static_cast<std::uint8_t>(c >> 8));
packet.push_back(static_cast<std::uint8_t>(c & 0xFF));
show("intact packet: ", checksum(packet));
packet[2] ^= 0x01;
show("one bit flipped: ", checksum(packet));
}