#include <iostream>
#include <inttypes.h>
uint64_t fletcher64_A(const uint8_t * data, uint64_t count)
{
// calculate how many full double words the input has
uint64_t dwords = count / 4;
// now calculate the flechter-64 checksum from double words
uint64_t sum1 = 0;
uint64_t sum2 = 0;
const uint32_t * data32 = reinterpret_cast<const uint32_t*>(data);
for (uint64_t index = 0; index < dwords; ++index)
{
sum1 = (sum1 + data32[index]) % UINT32_MAX;
sum2 = (sum2 + sum1) % UINT32_MAX;
}
// calculate how many extra bytes, that do not fit into a double word, the input has
uint64_t remainingBytes = count - dwords * 4;
if (remainingBytes > 0)
{
// copy the excess bytes to our dummy variable. you could use memcpy here...
uint32_t dummy = 0;
for (uint64_t index = 0; index < remainingBytes; ++index)
{
reinterpret_cast<uint8_t*>(&dummy)[index] = data[dwords * 4 + index];
}
// now add the dummy on top
sum1 = (sum1 + dummy) % UINT32_MAX;
sum2 = (sum2 + sum1) % UINT32_MAX;
}
// build final checksum
return (sum2 << 32) | sum1;
}
uint64_t fletcher64_B(const uint8_t * data, uint64_t count)
{
// calculate how many full double words the input has
uint64_t dwords = count / 4;
// now calculate the flechter-64 checksum from double words
uint32_t sum1 = 0;
uint32_t sum2 = 0;
const uint32_t * data32 = reinterpret_cast<const uint32_t*>(data);
for (uint64_t index = 0; index < dwords; ++index)
{
sum1 += data32[index];
sum2 += sum1;
}
// calculate how many extra bytes, that do not fit into a double word, the input has
uint64_t remainingBytes = count - dwords * 4;
if (remainingBytes > 0)
{
// copy the excess bytes to our dummy variable. you could use memcpy here...
uint32_t dummy = 0;
for (uint64_t index = 0; index < remainingBytes; ++index)
{
reinterpret_cast<uint8_t*>(&dummy)[index] = data[dwords * 4 + index];
}
// now add the dummy on top
sum1 += dummy;
sum2 += sum1;
}
// build final checksum
return ((uint64_t)sum2 << 32) | sum1;
}
int main() {
const std::string data = "abcdefghijklmnopqrstuvwxyz0123456789helloworld!";
uint64_t ca = fletcher64_A(reinterpret_cast<const uint8_t*>(data.data()), data.size());
uint64_t cb = fletcher64_B(reinterpret_cast<const uint8_t*>(data.data()), data.size());
std::cout << "String size: " << data.size() << ", checksum a: 0x" << std::hex << ca << ", checksum b: 0x" << cb << std::endl;
return 0;
}