mirror of
https://github.com/aaru-dps/Aaru.Checksums.Native.git
synced 2025-12-16 11:14:29 +00:00
Use multiple sum algorithm from zlib for Adler and Fletcher checksums.
This commit is contained in:
131
fletcher32.c
131
fletcher32.c
@@ -38,15 +38,138 @@ AARU_EXPORT fletcher32_ctx* AARU_CALL fletcher32_init()
|
||||
|
||||
AARU_EXPORT int AARU_CALL fletcher32_update(fletcher32_ctx* ctx, const uint8_t* data, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
if(!ctx || !data) return -1;
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
uint32_t sum1 = ctx->sum1;
|
||||
uint32_t sum2 = ctx->sum2;
|
||||
unsigned n;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if(len == 1)
|
||||
{
|
||||
ctx->sum1 = (ctx->sum1 + data[i]) % FLETCHER32_MODULE;
|
||||
ctx->sum2 = (ctx->sum2 + ctx->sum1) % FLETCHER32_MODULE;
|
||||
sum1 += data[0];
|
||||
if(sum1 >= FLETCHER32_MODULE) sum1 -= FLETCHER32_MODULE;
|
||||
sum2 += sum1;
|
||||
if(sum2 >= FLETCHER32_MODULE) sum2 -= FLETCHER32_MODULE;
|
||||
|
||||
ctx->sum1 = sum1 & 0xFFFF;
|
||||
ctx->sum2 = sum2 & 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if(len < 16)
|
||||
{
|
||||
while(len--)
|
||||
{
|
||||
sum1 += *data++;
|
||||
sum2 += sum1;
|
||||
}
|
||||
if(sum1 >= FLETCHER32_MODULE) sum1 -= FLETCHER32_MODULE;
|
||||
sum2 %= FLETCHER32_MODULE; /* only added so many FLETCHER32_MODULE's */
|
||||
ctx->sum1 = sum1 & 0xFFFF;
|
||||
ctx->sum2 = sum2 & 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while(len >= NMAX)
|
||||
{
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
sum1 += (data)[0];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
/* 16 sums unrolled */
|
||||
data += 16;
|
||||
} while(--n);
|
||||
sum1 %= FLETCHER32_MODULE;
|
||||
sum2 %= FLETCHER32_MODULE;
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if(len)
|
||||
{ /* avoid modulos if none remaining */
|
||||
while(len >= 16)
|
||||
{
|
||||
len -= 16;
|
||||
sum1 += (data)[0];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[0 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 1];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 2];
|
||||
sum2 += sum1;
|
||||
sum1 += (data)[8 + 4 + 2 + 1];
|
||||
sum2 += sum1;
|
||||
|
||||
data += 16;
|
||||
}
|
||||
while(len--)
|
||||
{
|
||||
sum1 += *data++;
|
||||
sum2 += sum1;
|
||||
}
|
||||
sum1 %= FLETCHER32_MODULE;
|
||||
sum2 %= FLETCHER32_MODULE;
|
||||
}
|
||||
|
||||
ctx->sum1 = sum1 & 0xFFFF;
|
||||
ctx->sum2 = sum2 & 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user