fletcher32.c
Go to the documentation of this file.
00001
00038 #include "fletcher32.h"
00039 #include <cfg/macros.h> //MIN()
00040
00041 void fletcher32_init(Fletcher32 *f)
00042 {
00043     f->sum1 = 0xFFFF;
00044     f->sum2 = 0xFFFF;
00045     f->carry = -1;
00046 }
00047
00048 void fletcher32_update(Fletcher32 *f, const void *_buf, size_t len)
00049 {
00050     uint16_t data = 0;
00051     const uint8_t *buf = (const uint8_t *)_buf;
00052     uint8_t last = buf[len-1];
00053
00054     if (f->carry != -1 && len)
00055     {
00056         data = f->carry | *buf++ << 8;
00057         f->carry = -1;
00058         ++len;
00059     }
00060     else if (len > 1)
00061     {
00062         data = buf[0] | buf[1] << 8;
00063         buf += 2;
00064     }
00065
00066     if (len & 1)
00067         f->carry = last;
00068
00069     size_t l = len / 2;
00070     while (l)
00071     {
00072         size_t tlen = MIN(l, (size_t)360);
00073         l -= tlen;
00074         do
00075         {
00076             f->sum1 += data;
00077             f->sum2 += f->sum1;
00078             data = buf[0] | buf[1] << 8;
00079             buf += 2;
00080         }
00081         while (--tlen);
00082         f->sum1 = (f->sum1 & 0xffff) + (f->sum1 >> 16);
00083         f->sum2 = (f->sum2 & 0xffff) + (f->sum2 >> 16);
00084     }
00085 }
00086
00087 uint32_t fletcher32_final(Fletcher32 *f)
00088 {
00089     uint32_t sum1, sum2;
00090     sum1 = f->sum1;
00091     sum2 = f->sum2;
00092
00093     if (f->carry != -1)
00094     {
00095         sum1 += f->carry;
00096         sum2 += sum1;
00097         sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00098         sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00099     }
00100
00101     /* Second reduction step to reduce sums to 16 bits */
00102     sum1 = (sum1 & 0xffff) + (sum1 >> 16);
00103     sum2 = (sum2 & 0xffff) + (sum2 >> 16);
00104
00105     return sum2 << 16 | sum1;
00106 }