Fletcher16: extend with multi-part functions

This commit extends the fletcher16 function with a set of init, update
and finish functions to allow for multi-part checksums. This is useful
when the data that has to be checksummed is not available in a single
continuous buffer.
This commit is contained in:
Koen Zandberg 2018-10-23 15:54:24 +02:00
parent 4d85bcf510
commit 230c5b89de
No known key found for this signature in database
GPG Key ID: 0895A893E6D2985B
2 changed files with 72 additions and 15 deletions

View File

@ -20,21 +20,41 @@
#include "checksum/fletcher16.h"
static inline void _reduce(fletcher16_ctx_t *ctx)
{
ctx->sum1 = (ctx->sum1 & 0xff) + (ctx->sum1 >> 8);
ctx->sum2 = (ctx->sum2 & 0xff) + (ctx->sum2 >> 8);
}
void fletcher16_init(fletcher16_ctx_t *ctx)
{
ctx->sum1 = 0xff;
ctx->sum2 = 0xff;
}
void fletcher16_update(fletcher16_ctx_t *ctx, const uint8_t *data, size_t len)
{
while (len) {
size_t tlen = len > 20 ? 20 : len;
len -= tlen;
do {
ctx->sum2 += ctx->sum1 += *data++;
} while (--tlen);
_reduce(ctx);
}
}
uint16_t fletcher16_finish(fletcher16_ctx_t *ctx)
{
/* Second reduction step to reduce sums to 8 bits */
_reduce(ctx);
return (ctx->sum2 << 8) | ctx->sum1;
}
uint16_t fletcher16(const uint8_t *data, size_t bytes)
{
uint16_t sum1 = 0xff, sum2 = 0xff;
while (bytes) {
size_t tlen = bytes > 20 ? 20 : bytes;
bytes -= tlen;
do {
sum2 += sum1 += *data++;
} while (--tlen);
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
}
/* Second reduction step to reduce sums to 8 bits */
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
return (sum2 << 8) | sum1;
fletcher16_ctx_t ctx;
fletcher16_init(&ctx);
fletcher16_update(&ctx, data, bytes);
return fletcher16_finish(&ctx);
}

View File

@ -27,8 +27,17 @@
extern "C" {
#endif
/**
* @brief Fletcher's 16 bit checksum context struct
*/
typedef struct {
uint16_t sum1; /**< First sum of the checksum */
uint16_t sum2; /**< Second sum of the checksum */
} fletcher16_ctx_t;
/**
* @brief Fletcher's 16 bit checksum
* @anchor fletcher16_full
*
* found on
* http://en.wikipedia.org/w/index.php?title=Fletcher%27s_checksum&oldid=661273016#Optimizations
@ -41,6 +50,34 @@ extern "C" {
*/
uint16_t fletcher16(const uint8_t *buf, size_t bytes);
/**
* @brief Initialize a fletcher16 context
*
* Multi-part version of @ref fletcher16_full.
*
* @param[in] ctx fletcher16 context to initialize
*/
void fletcher16_init(fletcher16_ctx_t *ctx);
/**
* @brief Update the fletcher16 context with new data
*
* @param[in] ctx fletcher16 context
* @param[in] data Data to add to the context
* @param[in] len Length of the data
*/
void fletcher16_update(fletcher16_ctx_t *ctx, const uint8_t *data, size_t len);
/**
* @brief Finalize the checksum operation and return the checksum
*
* @param[in] ctx fletcher16 context
*
* @return Checksum of the data
*/
uint16_t fletcher16_finish(fletcher16_ctx_t *ctx);
#ifdef __cplusplus
}