mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.0 Adler
This commit is contained in:
parent
625779fd3d
commit
4df9ffbd6f
@ -2,13 +2,13 @@ compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- due
|
||||
- zero
|
||||
- leonardo
|
||||
- m4
|
||||
- esp32
|
||||
# - esp8266
|
||||
# - mega2560
|
||||
- esp8266
|
||||
- mega2560
|
||||
|
||||
libraries:
|
||||
- "printHelpers"
|
||||
|
@ -1,158 +1,17 @@
|
||||
//
|
||||
// FILE: Adler.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.2
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// PURPOSE: Arduino Library for calculating Adler checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
//
|
||||
// HISTORY
|
||||
// 0.1.0 2022-01-27 initial version
|
||||
// 0.1.1 2022-04-15 split of .cpp file
|
||||
// 0.1.2 2022-06-13 split interface and implementation
|
||||
// rename ADLER32_MOD_PRIME
|
||||
// rename ADLER32_LIB_VERSION
|
||||
// add addFast(array, length)
|
||||
// add char interfaces
|
||||
// (no Adler16 reference, implementation is experimental)
|
||||
|
||||
|
||||
#include "Adler.h"
|
||||
|
||||
|
||||
Adler32::Adler32()
|
||||
{
|
||||
begin(1, 0);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::begin(uint32_t s1, uint32_t s2)
|
||||
{
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
||||
// reference implementation
|
||||
void Adler32::add(uint8_t value)
|
||||
{
|
||||
_count++;
|
||||
_s1 += value;
|
||||
if (_s1 >= ADLER32_MOD_PRIME) _s1 -= ADLER32_MOD_PRIME;
|
||||
_s2 += _s1;
|
||||
if (_s2 >= ADLER32_MOD_PRIME) _s2 -= ADLER32_MOD_PRIME;
|
||||
}
|
||||
|
||||
|
||||
// optimized version (~10% gain)
|
||||
// void Adler32::add(uint8_t value)
|
||||
// {
|
||||
// _count++;
|
||||
// _s1 += value;
|
||||
// _s2 += _s1;
|
||||
// if (_s2 >= ADLER32_MOD_PRIME)
|
||||
// {
|
||||
// _s2 -= ADLER32_MOD_PRIME;
|
||||
// if (_s1 >= ADLER32_MOD_PRIME) _s1 -= ADLER32_MOD_PRIME;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// straightforward going through the array.
|
||||
void Adler32::add(uint8_t * array, uint16_t length)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
add(*array++);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// optimized version (under test)
|
||||
// S1 grows linear
|
||||
// S2 grows quadratic
|
||||
// as S2 grows faster than S1, S1 needs only to be checked
|
||||
// if S2 hits the ADLER32_MOD_PRIME and probably far less.
|
||||
//
|
||||
// void Adler32::addFast(uint8_t * array, uint16_t length)
|
||||
// {
|
||||
// _count += length;
|
||||
// while (length--)
|
||||
// {
|
||||
// _s1 += *array++;
|
||||
// _s2 += _s1;
|
||||
// if (_s2 >= ADLER32_MOD_PRIME)
|
||||
// {
|
||||
// _s2 -= ADLER32_MOD_PRIME;
|
||||
// if (_s1 >= ADLER32_MOD_PRIME)
|
||||
// {
|
||||
// _s1 -= ADLER32_MOD_PRIME;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// further optimized version (under test)
|
||||
// S1 grows linear
|
||||
// S2 grows quadratic
|
||||
// only do modulo when we reach halfway uint32_t
|
||||
// or when really needed.
|
||||
void Adler32::addFast(uint8_t * array, uint16_t length)
|
||||
{
|
||||
_count += length;
|
||||
uint32_t s1 = _s1;
|
||||
uint32_t s2 = _s2;
|
||||
for (uint16_t i = 0; i < length;)
|
||||
{
|
||||
// if S2 is halfway it is time to do modulo
|
||||
while ((i < length) && (s2 < 2147483648ULL))
|
||||
{
|
||||
s1 += array[i++];
|
||||
s2 += s1;
|
||||
}
|
||||
if (s2 >= ADLER32_MOD_PRIME)
|
||||
{
|
||||
s2 %= ADLER32_MOD_PRIME;
|
||||
if (s1 >= ADLER32_MOD_PRIME) s1 %= ADLER32_MOD_PRIME;
|
||||
}
|
||||
}
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wrapper for strings.
|
||||
//
|
||||
void Adler32::add(char value)
|
||||
{
|
||||
add((uint8_t) value);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::add(char * array, uint16_t length)
|
||||
{
|
||||
add((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::addFast(char * array, uint16_t length)
|
||||
{
|
||||
addFast((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
uint32_t Adler32::getAdler()
|
||||
{
|
||||
return (_s2 << 16) | _s1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// STATIC FUNCTION
|
||||
@ -176,5 +35,24 @@ uint32_t adler32(uint8_t * array, uint16_t length)
|
||||
}
|
||||
|
||||
|
||||
uint16_t adler16(uint8_t * array, uint16_t length)
|
||||
{
|
||||
uint16_t s1 = 1;
|
||||
uint16_t s2 = 0;
|
||||
for (uint16_t i = 0; i < length;)
|
||||
{
|
||||
// if S2 is halfway it is time to do modulo
|
||||
while ((i < length) && (s2 < 32768))
|
||||
{
|
||||
s1 += array[i++];
|
||||
s2 += s1;
|
||||
}
|
||||
s1 %= ADLER16_MOD_PRIME;
|
||||
s2 %= ADLER16_MOD_PRIME;
|
||||
}
|
||||
return (s2 << 8) | s1;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
//
|
||||
// FILE: Adler.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.2
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// PURPOSE: Arduino Library for calculating Adler checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
|
||||
@ -12,11 +12,11 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER32_LIB_VERSION (F("0.1.2"))
|
||||
#define ADLER_LIB_VERSION (F("0.2.0"))
|
||||
|
||||
|
||||
const uint16_t ADLER32_MOD_PRIME = 65521;
|
||||
|
||||
const uint32_t ADLER32_MOD_PRIME = 65521;
|
||||
const uint16_t ADLER16_MOD_PRIME = 251;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
@ -24,39 +24,7 @@ const uint16_t ADLER32_MOD_PRIME = 65521;
|
||||
// STATIC FUNCTIONS
|
||||
//
|
||||
uint32_t adler32(uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// CLASS VERSION
|
||||
//
|
||||
class Adler32
|
||||
{
|
||||
public:
|
||||
Adler32();
|
||||
|
||||
void begin(uint32_t s1 = 1, uint32_t s2 = 0);
|
||||
|
||||
void add(uint8_t value);
|
||||
void add(uint8_t * array, uint16_t length);
|
||||
// trade PROGMEM for speed
|
||||
void addFast(uint8_t * array, uint16_t length);
|
||||
|
||||
// wrappers for strings
|
||||
void add(char value);
|
||||
void add(char * array, uint16_t length);
|
||||
void addFast(char * array, uint16_t length);
|
||||
|
||||
|
||||
uint32_t getAdler();
|
||||
uint32_t count() { return _count; };
|
||||
|
||||
private:
|
||||
uint32_t _s1;
|
||||
uint32_t _s2;
|
||||
uint32_t _count;
|
||||
};
|
||||
uint16_t adler16(uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
127
libraries/Adler/Adler16.cpp
Normal file
127
libraries/Adler/Adler16.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// FILE: Adler16.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-06-14
|
||||
// PURPOSE: Arduino Library for calculating Adler-16 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
// (no Adler16 reference, implementation is experimental)
|
||||
//
|
||||
// HISTORY: see CHANGELOG.md
|
||||
|
||||
|
||||
|
||||
#include "Adler16.h"
|
||||
|
||||
|
||||
Adler16::Adler16()
|
||||
{
|
||||
begin(1, 0);
|
||||
}
|
||||
|
||||
|
||||
void Adler16::begin(uint16_t s1, uint16_t s2)
|
||||
{
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
||||
// reference implementation
|
||||
// void Adler16::add(uint8_t value)
|
||||
// {
|
||||
// _count++;
|
||||
// _s1 += value;
|
||||
// if (_s1 >= ADLER16_MOD_PRIME) _s1 -= ADLER16_MOD_PRIME;
|
||||
// _s2 += _s1;
|
||||
// if (_s2 >= ADLER16_MOD_PRIME) _s2 -= ADLER16_MOD_PRIME;
|
||||
// }
|
||||
|
||||
|
||||
// optimized version (~10% faster)
|
||||
void Adler16::add(uint8_t value)
|
||||
{
|
||||
_count++;
|
||||
_s1 += value;
|
||||
_s2 += _s1;
|
||||
if (_s2 >= ADLER16_MOD_PRIME)
|
||||
{
|
||||
_s2 -= ADLER16_MOD_PRIME;
|
||||
if (_s1 >= ADLER16_MOD_PRIME) _s1 -= ADLER16_MOD_PRIME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// straightforward going through the array.
|
||||
// small footprint
|
||||
void Adler16::add(uint8_t * array, uint16_t length)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
add(*array++);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Optimized version
|
||||
// S1 grows linear
|
||||
// S2 grows quadratic
|
||||
// only do modulo when S2 reaches halfway uint16_t
|
||||
// and at the end of the loop.
|
||||
void Adler16::addFast(uint8_t * array, uint16_t length)
|
||||
{
|
||||
_count += length;
|
||||
uint16_t s1 = _s1;
|
||||
uint16_t s2 = _s2;
|
||||
for (uint16_t i = 0; i < length;)
|
||||
{
|
||||
// if S2 is halfway it is time to do modulo
|
||||
while ((i < length) && (s2 < 32768))
|
||||
{
|
||||
s1 += array[i++];
|
||||
s2 += s1;
|
||||
}
|
||||
if (s2 >= ADLER16_MOD_PRIME)
|
||||
{
|
||||
s2 %= ADLER16_MOD_PRIME;
|
||||
if (s1 >= ADLER16_MOD_PRIME) s1 %= ADLER16_MOD_PRIME;
|
||||
}
|
||||
}
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
}
|
||||
|
||||
|
||||
uint16_t Adler16::getAdler()
|
||||
{
|
||||
return (_s2 << 8) | _s1;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wrappers for strings.
|
||||
//
|
||||
void Adler16::add(char value)
|
||||
{
|
||||
add((uint8_t) value);
|
||||
}
|
||||
|
||||
|
||||
void Adler16::add(char * array, uint16_t length)
|
||||
{
|
||||
add((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
void Adler16::addFast(char * array, uint16_t length)
|
||||
{
|
||||
addFast((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
52
libraries/Adler/Adler16.h
Normal file
52
libraries/Adler/Adler16.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: Adler16.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-06-15
|
||||
// PURPOSE: Arduino Library for calculating Adler-16 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
// (no Adler16 reference, implementation is experimental)
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER16_LIB_VERSION (F("0.2.0"))
|
||||
|
||||
|
||||
// largest prime below 2^8
|
||||
const uint16_t ADLER16_MOD_PRIME = 251;
|
||||
|
||||
class Adler16
|
||||
{
|
||||
public:
|
||||
Adler16();
|
||||
|
||||
void begin(uint16_t s1 = 1, uint16_t s2 = 0);
|
||||
|
||||
void add(uint8_t value);
|
||||
void add(uint8_t * array, uint16_t length);
|
||||
// trade PROGMEM for speed
|
||||
void addFast(uint8_t * array, uint16_t length);
|
||||
|
||||
// wrappers for strings
|
||||
void add(char value);
|
||||
void add(char * array, uint16_t length);
|
||||
void addFast(char * array, uint16_t length);
|
||||
|
||||
|
||||
uint16_t getAdler();
|
||||
uint16_t count() { return _count; };
|
||||
|
||||
private:
|
||||
uint16_t _s1;
|
||||
uint16_t _s2;
|
||||
uint32_t _count;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
127
libraries/Adler/Adler32.cpp
Normal file
127
libraries/Adler/Adler32.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// FILE: Adler32.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
//
|
||||
// HISTORY: see CHANGELOG.md
|
||||
|
||||
|
||||
|
||||
#include "Adler32.h"
|
||||
|
||||
|
||||
Adler32::Adler32()
|
||||
{
|
||||
begin(1, 0);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::begin(uint32_t s1, uint32_t s2)
|
||||
{
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
|
||||
// reference implementation
|
||||
// void Adler32::add(uint8_t value)
|
||||
// {
|
||||
// _count++;
|
||||
// _s1 += value;
|
||||
// if (_s1 >= ADLER32_MOD_PRIME) _s1 -= ADLER32_MOD_PRIME;
|
||||
// _s2 += _s1;
|
||||
// if (_s2 >= ADLER32_MOD_PRIME) _s2 -= ADLER32_MOD_PRIME;
|
||||
// }
|
||||
|
||||
|
||||
// optimized version (~10% faster)
|
||||
void Adler32::add(uint8_t value)
|
||||
{
|
||||
_count++;
|
||||
_s1 += value;
|
||||
_s2 += _s1;
|
||||
if (_s2 >= ADLER32_MOD_PRIME)
|
||||
{
|
||||
_s2 -= ADLER32_MOD_PRIME;
|
||||
if (_s1 >= ADLER32_MOD_PRIME) _s1 -= ADLER32_MOD_PRIME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// straightforward going through the array.
|
||||
// small footprint.
|
||||
void Adler32::add(uint8_t * array, uint16_t length)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
add(*array++);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Optimized version
|
||||
// S1 grows linear
|
||||
// S2 grows quadratic
|
||||
// only do modulo when S2 reaches halfway uint32_t
|
||||
// and at the end of the loop.
|
||||
void Adler32::addFast(uint8_t * array, uint16_t length)
|
||||
{
|
||||
_count += length;
|
||||
uint32_t s1 = _s1;
|
||||
uint32_t s2 = _s2;
|
||||
for (uint16_t i = 0; i < length;)
|
||||
{
|
||||
// if S2 is halfway it is time to do modulo
|
||||
while ((i < length) && (s2 < 2147483648ULL))
|
||||
{
|
||||
s1 += array[i++];
|
||||
s2 += s1;
|
||||
}
|
||||
if (s2 >= ADLER32_MOD_PRIME)
|
||||
{
|
||||
s2 %= ADLER32_MOD_PRIME;
|
||||
if (s1 >= ADLER32_MOD_PRIME) s1 %= ADLER32_MOD_PRIME;
|
||||
}
|
||||
}
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Adler32::getAdler()
|
||||
{
|
||||
return (_s2 << 16) | _s1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wrappers for strings.
|
||||
//
|
||||
void Adler32::add(char value)
|
||||
{
|
||||
add((uint8_t) value);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::add(char * array, uint16_t length)
|
||||
{
|
||||
add((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::addFast(char * array, uint16_t length)
|
||||
{
|
||||
addFast((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
52
libraries/Adler/Adler32.h
Normal file
52
libraries/Adler/Adler32.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: Adler.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
// https://en.wikipedia.org/wiki/Adler-32
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER32_LIB_VERSION (F("0.2.0"))
|
||||
|
||||
|
||||
// largest prime below 2^16
|
||||
const uint32_t ADLER32_MOD_PRIME = 65521;
|
||||
|
||||
|
||||
class Adler32
|
||||
{
|
||||
public:
|
||||
Adler32();
|
||||
|
||||
void begin(uint32_t s1 = 1, uint32_t s2 = 0);
|
||||
|
||||
void add(uint8_t value);
|
||||
void add(uint8_t * array, uint16_t length);
|
||||
// trade PROGMEM for speed
|
||||
void addFast(uint8_t * array, uint16_t length);
|
||||
|
||||
// wrappers for strings
|
||||
void add(char value);
|
||||
void add(char * array, uint16_t length);
|
||||
void addFast(char * array, uint16_t length);
|
||||
|
||||
|
||||
uint32_t getAdler();
|
||||
uint32_t count() { return _count; };
|
||||
|
||||
private:
|
||||
uint32_t _s1;
|
||||
uint32_t _s2;
|
||||
uint32_t _count;
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
34
libraries/Adler/CHANGELOG.md
Normal file
34
libraries/Adler/CHANGELOG.md
Normal file
@ -0,0 +1,34 @@
|
||||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.2.0] - 2022-06-15
|
||||
|
||||
- breaking change
|
||||
- reordering files.
|
||||
- Adler.h for static functions
|
||||
- Adler32.h for Adler32 class
|
||||
- Adler16.h for Adler16 class (experimental).
|
||||
- Added optimizations.
|
||||
|
||||
## [0.1.2] - 2022-06-13
|
||||
|
||||
- split interface and implementation
|
||||
- rename ADLER32_MOD_PRIME
|
||||
- rename ADLER32_LIB_VERSION
|
||||
- add addFast(array, length)
|
||||
- add char interfaces
|
||||
|
||||
## [0.1.1] - 2022-04-15
|
||||
|
||||
- split of .cpp file
|
||||
|
||||
### [0.1.0] - 2022-01-27
|
||||
|
||||
- initial version
|
||||
|
||||
|
||||
|
@ -8,12 +8,16 @@
|
||||
|
||||
# Adler
|
||||
|
||||
Arduino Library for Adler-32 checksum
|
||||
Arduino Library for Adler-32 and experimental Adler-16 checksum.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
This library provides a Adler checksum of a data array.
|
||||
This library provides a Adler32 checksum of a data array.
|
||||
Furthermore since 0.2.0 an experimental Adler-16 implementation is added.
|
||||
This one is often faster as it uses a smaller checksum than the Adler32,
|
||||
and the price is that it is less sensitive than the Adler32.
|
||||
Still it might have its niches where it will be useful.
|
||||
|
||||
Relates to https://github.com/RobTillaart/CRC
|
||||
|
||||
@ -21,13 +25,21 @@ Relates to https://github.com/RobTillaart/Fletcher
|
||||
|
||||
Tested on Arduino UNO only.
|
||||
|
||||
0.2.0 is a breaking change, file names have been changed to be more
|
||||
in line with the CRC library.
|
||||
- Adler.h for the static functions
|
||||
- Adler32.h for the Adler32 class
|
||||
- Adler16.h for the Adler16 class.
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
|
||||
## Adler class
|
||||
### Adler class
|
||||
|
||||
Use **\#include "Adler.h"**
|
||||
Use **\#include "Adler32.h"** or **\#include "Adler16.h"**
|
||||
|
||||
The interface for the Adler16 is very similar.
|
||||
|
||||
- **Adler32()** Constructor, initializes internals.
|
||||
- **void begin(uint8_t s1 = 1, uint8_t s2 = 0)** resets the internals.
|
||||
@ -43,58 +55,142 @@ The class is typically used for streaming very large blocks of data,
|
||||
optional with intermediate checksum tests.
|
||||
|
||||
|
||||
#### Performance
|
||||
## Performance Adler32
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
First numbers of **.add(value)** measured with test sketch shows the following timing.
|
||||
|
||||
| Version | Checksum | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:------------:|:---------------:|
|
||||
| 0.1.0 | Adler32 | 5.6 us | |
|
||||
| 0.1.2 | Adler32 | 6.6 us | |
|
||||
|
||||
Todo elaborate / investigate.
|
||||
Numbers measured with **Adler32_performance.ino**.
|
||||
|
||||
|
||||
#### Performance 2
|
||||
### add(value)
|
||||
|
||||
(since 0.1.2)
|
||||
The **add(value)** adds one byte and does a subtraction
|
||||
instead of a modulo.
|
||||
|
||||
The **addFast(array, length)** is faster than the reference **add(array, length)** but uses 108 bytes more, so a slightly larger footprint.
|
||||
So depending on your needs, you choose performance or footprint.
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | add | 5.6 us | |
|
||||
| 0.1.2 | add | 6.6 us | |
|
||||
| 0.2.0 | add | 5.9 us | |
|
||||
|
||||
|
||||
### add(lorem) 868 chars
|
||||
|
||||
The **add(array, length)** is a straightforward loop
|
||||
over the array and has a small footprint.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | add | | |
|
||||
| 0.1.2 | add | 6392 us | |
|
||||
| 0.2.0 | add | 5748 us | |
|
||||
|
||||
Note: **add()** is about 6.6 us per byte.
|
||||
|
||||
|
||||
### addFast(lorem) 868 chars
|
||||
|
||||
The **addFast(array, length)** is faster than the
|
||||
reference **add(array, length)** and uses 108 bytes more.
|
||||
So the function has a larger footprint.
|
||||
Depending on your needs, choose performance or footprint.
|
||||
|
||||
See **Adler32_performance_addFast.ino**
|
||||
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | addFast | | |
|
||||
| 0.1.2 | addFast | 1348 us | |
|
||||
| 0.2.0 | addFast | 1348 us | |
|
||||
|
||||
Note: **addFast()** is less than 2 us per byte.
|
||||
|
||||
|
||||
|
||||
## Performance Adler16
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
|
||||
Numbers measured with **Adler16_performance.ino**.
|
||||
|
||||
|
||||
### add(value)
|
||||
|
||||
The **add(value)** adds one byte and does a subtraction
|
||||
instead of a modulo.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | add | 4.0 us | |
|
||||
|
||||
The per byte performance of the Adler16 (on UNO) is faster
|
||||
than the Adler32 **add(value)**. The reason is that a 16 bit
|
||||
subtraction on an UNO is faster than a 32 bit subtraction.
|
||||
|
||||
|
||||
### add(lorem) 868 chars
|
||||
|
||||
The **add(array, length)** is a straightforward loop
|
||||
over the array and has a small footprint.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | add | 4040 us | |
|
||||
|
||||
Note: **add()** is about 6.6 us per byte.
|
||||
|
||||
|
||||
### addFast(lorem) 868 chars
|
||||
|
||||
The **addFast(array, length)** is faster than the
|
||||
reference **add(array, length)**.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | addFast | 1968 us | |
|
||||
|
||||
The gain of the faster 16 bit modulo meets the frequency of
|
||||
doing the modulo more often.
|
||||
|
||||
|
||||
## Interface static functions
|
||||
|
||||
The function is straightforward.
|
||||
The functions are straightforward.
|
||||
|
||||
Use **\#include "Adler.h"**
|
||||
|
||||
- **uint32_t adler32(uint8_t \*data, uint16_t length)** length in units of 1 byte = 8 bits.
|
||||
- **uint16_t adler16(uint8_t \*data, uint16_t length)** length in units of 1 byte = 8 bits.
|
||||
|
||||
The function is typically used for an in memory buffer to calculate
|
||||
the Adler checksum once.
|
||||
The functions are typically used for an in memory buffer to calculate the checksum once.
|
||||
Think of packets in a network, records in a database, or a checksum for an configuration in EEPROM.
|
||||
|
||||
|
||||
#### Performance
|
||||
### Performance
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
|
||||
Not tested extensively, first numbers of **.add(array, length)**
|
||||
measured with **Adler_performance.ino** sketch shows the following timing.
|
||||
Numbers measured with **Adler_performance.ino**.
|
||||
|
||||
Lorem Ipsum text = 868 bytes.
|
||||
|
||||
| Checksum | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:------------|:-----------:|:-------------:|
|
||||
| Adler32 | 1116 us | |
|
||||
|
||||
Average 1116 / 868 = 1.29 us per byte.
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | Adler32 | 1116 us | |
|
||||
| 0.1.2 | Adler32 | 1116 us | |
|
||||
| 0.2.0 | Adler32 | 1116 us | |
|
||||
| 0.2.0 | Adler16 | 1736 us | |
|
||||
|
||||
|
||||
Adler32 average 1116 / 868 = 1.29 us per byte.
|
||||
Adler16 average 1736 / 868 = 2.00 us per byte. (~1.5x slower !)
|
||||
|
||||
Adler16 does more often the modulo math as it reaches halfway uint16_t
|
||||
faster than Adler32 reaches halfway uint32_t.
|
||||
|
||||
As the Adler16 is less performant as the Adler32, it is often the best to use
|
||||
the 32 bit version.
|
||||
|
||||
|
||||
## Operation
|
||||
@ -104,9 +200,17 @@ See examples.
|
||||
|
||||
## Future
|
||||
|
||||
- test other platforms
|
||||
- add Adler-16, similar algorithm
|
||||
- ADLER16_MOD_PRIME 32749 = largest prime below 2^15 (32768)
|
||||
- (0.2.0)
|
||||
- return values for **add(array)** and **addFast(array)**
|
||||
- updated checksum?
|
||||
- not for **add(value)** as that would create quite some overhead.
|
||||
- Adler64 ?
|
||||
- would need a large prime (which)
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
- do the string wrappers need strlen() ? parameter.
|
||||
- yes, as string can be processed partially.
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,178 @@
|
||||
//
|
||||
// FILE: Adler16_performance.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler16.h"
|
||||
|
||||
|
||||
Adler16 ad;
|
||||
volatile uint8_t z;
|
||||
uint32_t start, stop, randomtime;
|
||||
|
||||
char lorem[] = "Lorem ipsum dolor sit amet, \
|
||||
consectetuer adipiscing elit. Aenean commodo ligula eget dolor. \
|
||||
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient \
|
||||
montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, \
|
||||
pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. \
|
||||
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. \
|
||||
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. \
|
||||
Nullam dictum felis eu pede mollis pretium. Integer tincidunt. \
|
||||
Cras dapibus. Vivamus elementum semper nisi. \
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, \
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, \
|
||||
viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus \
|
||||
varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies \
|
||||
nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
|
||||
|
||||
|
||||
char hello[] = "hello world";
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println();
|
||||
Serial.println("Adler16_performance");
|
||||
Serial.print("ADLER16_LIB_VERSION: ");
|
||||
Serial.println(ADLER16_LIB_VERSION);
|
||||
|
||||
start = micros();
|
||||
for (uint16_t x = 0; x < 10000; x++)
|
||||
{
|
||||
z = random(255);
|
||||
}
|
||||
stop = micros();
|
||||
randomtime = stop - start;
|
||||
Serial.print("randomtime: ");
|
||||
Serial.println(randomtime);
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
for (uint16_t x = 0; x < 10000; x++)
|
||||
{
|
||||
z = random(255);
|
||||
ad.add(z);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(" total: ");
|
||||
Serial.println(stop - start);
|
||||
Serial.print(" 1e4 x add: ");
|
||||
Serial.println(stop - start - randomtime);
|
||||
delay(100);
|
||||
|
||||
Serial.print(" checksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
for (uint32_t x = 0; x < 1000000; x++)
|
||||
{
|
||||
z = x & 0xFF;
|
||||
ad.add(z);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(" total: ");
|
||||
Serial.println(stop - start);
|
||||
Serial.print(" 1e6 x add: ");
|
||||
Serial.println(stop - start - randomtime);
|
||||
delay(100);
|
||||
Serial.print(" checksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
ad.begin();
|
||||
Serial.print("LENGTH LOREM: ");
|
||||
Serial.println(strlen(lorem));
|
||||
Serial.println();
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int i = 0; lorem[i] != 0; i++)
|
||||
{
|
||||
ad.add(lorem[i]);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(" lorem 1: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
ad.add(lorem, strlen(lorem));
|
||||
stop = micros();
|
||||
Serial.print(" lorem 2: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
ad.addFast(lorem, strlen(lorem));
|
||||
stop = micros();
|
||||
Serial.print(" lorem 3: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
Serial.println();
|
||||
delay(100);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
ad.begin();
|
||||
Serial.print("LENGTH HELLO: ");
|
||||
Serial.println(strlen(hello));
|
||||
Serial.println();
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int i = 0; hello[i] != 0; i++)
|
||||
{
|
||||
ad.add(hello[i]);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print(" hello 1: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
ad.add(hello, strlen(hello));
|
||||
stop = micros();
|
||||
Serial.print(" hello 2: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
delay(100);
|
||||
|
||||
ad.begin();
|
||||
start = micros();
|
||||
ad.addFast(hello, strlen(hello));
|
||||
stop = micros();
|
||||
Serial.print(" hello 3: ");
|
||||
Serial.print(stop - start);
|
||||
Serial.print("\tchecksum: ");
|
||||
Serial.println(ad.getAdler());
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,24 @@
|
||||
Adler16_performance
|
||||
ADLER16_LIB_VERSION: 0.1.0
|
||||
randomtime: 901476
|
||||
total: 942656
|
||||
1e4 x add: 41180
|
||||
checksum: 46478
|
||||
|
||||
total: 5157524
|
||||
1e6 x add: 4256048
|
||||
checksum: 63140
|
||||
|
||||
LENGTH LOREM: 868
|
||||
|
||||
lorem 1: 3792 checksum: 57303
|
||||
lorem 2: 4224 checksum: 57303
|
||||
lorem 3: 1972 checksum: 57303
|
||||
|
||||
LENGTH HELLO: 11
|
||||
|
||||
hello 1: 52 checksum: 36209
|
||||
hello 2: 60 checksum: 36209
|
||||
hello 3: 48 checksum: 36209
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
Adler16_performance
|
||||
ADLER16_LIB_VERSION: 0.2.0
|
||||
randomtime: 901476
|
||||
total: 941076
|
||||
1e4 x add: 39600
|
||||
checksum: 6798
|
||||
|
||||
total: 5000108
|
||||
1e6 x add: 4098632
|
||||
checksum: 5028
|
||||
|
||||
LENGTH LOREM: 868
|
||||
|
||||
lorem 1: 3600 checksum: 57303
|
||||
lorem 2: 4040 checksum: 57303
|
||||
lorem 3: 1968 checksum: 57303
|
||||
|
||||
LENGTH HELLO: 11
|
||||
|
||||
hello 1: 48 checksum: 36209
|
||||
hello 2: 56 checksum: 36209
|
||||
hello 3: 48 checksum: 36209
|
||||
|
52
libraries/Adler/examples/Adler16_test/Adler16_test.ino
Normal file
52
libraries/Adler/examples/Adler16_test/Adler16_test.ino
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// FILE: Adler16_test.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler16.h"
|
||||
|
||||
// expected output
|
||||
// Adler16_test
|
||||
// ADLER16_LIB_VERSION: 0.2.0
|
||||
// 6012
|
||||
// 7293
|
||||
// 6269
|
||||
|
||||
|
||||
Adler16 ad;
|
||||
|
||||
uint8_t arr1[5] = { 100, 120, 130, 135, 140 };
|
||||
uint8_t arr2[5] = { 101, 120, 130, 135, 140 }; // minimal diff.
|
||||
uint8_t arr3[5] = { 100, 120, 130, 135, 141 }; // minimal diff.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println();
|
||||
Serial.println("Adler16_test");
|
||||
Serial.print("ADLER16_LIB_VERSION: ");
|
||||
Serial.println(ADLER16_LIB_VERSION);
|
||||
|
||||
ad.begin();
|
||||
ad.add(arr1, 5);
|
||||
Serial.println(ad.getAdler());
|
||||
|
||||
ad.begin();
|
||||
ad.add(arr2, 5);
|
||||
Serial.println(ad.getAdler());
|
||||
|
||||
ad.begin();
|
||||
ad.add(arr3, 5);
|
||||
Serial.println(ad.getAdler());
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
5
libraries/Adler/examples/Adler16_test/output_0.1.0.txt
Normal file
5
libraries/Adler/examples/Adler16_test/output_0.1.0.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Adler16_test
|
||||
ADLER16_LIB_VERSION: 0.1.0
|
||||
7292
|
||||
8573
|
||||
7549
|
@ -4,8 +4,7 @@
|
||||
// PURPOSE: demo
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler.h"
|
||||
|
||||
#include "Adler32.h"
|
||||
|
||||
|
||||
Adler32 ad;
|
||||
|
@ -0,0 +1,24 @@
|
||||
Adler32_performance
|
||||
ADLER32_LIB_VERSION: 0.2.0
|
||||
randomtime: 901476
|
||||
total: 960236
|
||||
1e4 x add: 58760
|
||||
checksum: 1607808947
|
||||
|
||||
total: 6919548
|
||||
1e6 x add: 6018072
|
||||
checksum: 237492440
|
||||
|
||||
LENGTH LOREM: 868
|
||||
|
||||
lorem 1: 5308 checksum: 3972480156
|
||||
lorem 2: 5748 checksum: 3972480156
|
||||
lorem 3: 1348 checksum: 3972480156
|
||||
|
||||
LENGTH HELLO: 11
|
||||
|
||||
hello 1: 64 checksum: 436929629
|
||||
hello 2: 80 checksum: 436929629
|
||||
hello 3: 32 checksum: 436929629
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// PURPOSE: demo
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler.h"
|
||||
#include "Adler32.h"
|
||||
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@ nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
|
||||
char hello[] = "hello world";
|
||||
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
@ -4,10 +4,11 @@
|
||||
// PURPOSE: demo
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler.h"
|
||||
#include "Adler32.h"
|
||||
|
||||
// expected output
|
||||
// Adler32_test
|
||||
// ADLER32_LIB_VERSION: 0.2.0
|
||||
// 116982386
|
||||
// 117310067
|
||||
// 117047923
|
||||
@ -27,7 +28,9 @@ void setup()
|
||||
|
||||
Serial.println();
|
||||
Serial.println("Adler32_test");
|
||||
|
||||
Serial.print("ADLER32_LIB_VERSION: ");
|
||||
Serial.println(ADLER32_LIB_VERSION);
|
||||
|
||||
ad.begin();
|
||||
ad.add(arr1, 5);
|
||||
Serial.println(ad.getAdler());
|
||||
|
@ -30,8 +30,8 @@ void setup()
|
||||
while (!Serial);
|
||||
|
||||
Serial.println();
|
||||
Serial.print("ADLER32_LIB_VERSION: ");
|
||||
Serial.println(ADLER32_LIB_VERSION);
|
||||
Serial.print("ADLER_LIB_VERSION: ");
|
||||
Serial.println(ADLER_LIB_VERSION);
|
||||
|
||||
for (int i = 0; i < 60; i++)
|
||||
{
|
||||
@ -53,6 +53,18 @@ void setup()
|
||||
Serial.print(x);
|
||||
Serial.print("\t");
|
||||
Serial.println(x, HEX);
|
||||
delay(200);
|
||||
|
||||
|
||||
start = micros();
|
||||
volatile uint16_t y = adler16((uint8_t *) str, len);
|
||||
stop = micros();
|
||||
Serial.print(" TIME us: ");
|
||||
Serial.println(stop - start);
|
||||
Serial.print(" ADLER-16: ");
|
||||
Serial.print(y);
|
||||
Serial.print("\t");
|
||||
Serial.println(y, HEX);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
|
@ -9,13 +9,20 @@
|
||||
|
||||
|
||||
// expected output
|
||||
// ADLER32_LIB_VERSION: 0.1.2
|
||||
// ADLER_LIB_VERSION: 0.2.0
|
||||
//
|
||||
// E1F5
|
||||
// 4660
|
||||
// 4634
|
||||
// 40A7
|
||||
//
|
||||
// 5C801F0
|
||||
// 81E0256
|
||||
// E000325
|
||||
// 11E60398
|
||||
|
||||
|
||||
|
||||
char str1[24] = "abcde";
|
||||
char str2[24] = "abcdef";
|
||||
char str3[24] = "abcdefgh";
|
||||
@ -28,13 +35,21 @@ void setup()
|
||||
while (!Serial);
|
||||
|
||||
Serial.println();
|
||||
Serial.print("ADLER32_LIB_VERSION: ");
|
||||
Serial.println(ADLER32_LIB_VERSION);
|
||||
Serial.print("ADLER_LIB_VERSION: ");
|
||||
Serial.println(ADLER_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(adler16((uint8_t *) str1, 5), HEX);
|
||||
Serial.println(adler16((uint8_t *) str2, 6), HEX);
|
||||
Serial.println(adler16((uint8_t *) str3, 8), HEX);
|
||||
Serial.println(adler16((uint8_t *) str4, 9), HEX);
|
||||
Serial.println();
|
||||
|
||||
Serial.println(adler32((uint8_t *) str1, 5), HEX);
|
||||
Serial.println(adler32((uint8_t *) str2, 6), HEX);
|
||||
Serial.println(adler32((uint8_t *) str3, 8), HEX);
|
||||
Serial.println(adler32((uint8_t *) str4, 9), HEX);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
# Data types (KEYWORD1)
|
||||
Adler32 KEYWORD1
|
||||
Adler16 KEYWORD1
|
||||
|
||||
|
||||
# Methods and Functions (KEYWORD2)
|
||||
adler32 KEYWORD2
|
||||
adler16 KEYWORD2
|
||||
begin KEYWORD2
|
||||
add KEYWORD2
|
||||
addFast KEYWORD2
|
||||
@ -15,5 +17,7 @@ count KEYWORD2
|
||||
|
||||
# Constants (LITERAL1)
|
||||
ADLER32_LIB_VERSION LITERAL1
|
||||
ADLER16_LIB_VERSION LITERAL1
|
||||
ADLER32_MOD_PRIME LITERAL1
|
||||
ADLER16_MOD_PRIME LITERAL1
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Adler",
|
||||
"keywords": "Adler, checksum",
|
||||
"keywords": "Adler32, Adler16, checksum",
|
||||
"description": "Arduino Library for calculating Adler-32 checksum.",
|
||||
"authors":
|
||||
[
|
||||
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/Adler.git"
|
||||
},
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,11 +1,11 @@
|
||||
name=Adler
|
||||
version=0.1.2
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence="Arduino Library for calculating Adler-32 checksum.
|
||||
paragraph=
|
||||
sentence=Arduino Library for calculating Adler-32 and Adler-16 checksum.
|
||||
paragraph=Adler-16 is experimental.
|
||||
category=Signal Input/Output
|
||||
url=https://github.com/RobTillaart/Adler
|
||||
architectures=*
|
||||
includes=Adler.h
|
||||
includes=Adler.h,Adler16.h,Adler32.h
|
||||
depends=
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "Arduino.h"
|
||||
#include "Adler.h"
|
||||
|
||||
|
||||
char lorem[] = "Lorem ipsum dolor sit amet, \
|
||||
consectetuer adipiscing elit. Aenean commodo ligula eget dolor. \
|
||||
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient \
|
||||
@ -45,7 +46,7 @@ nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "ADLER32_LIB_VERSION: %s\n", (char *) ADLER32_LIB_VERSION);
|
||||
fprintf(stderr, "ADLER_LIB_VERSION: %s\n", (char *) ADLER_LIB_VERSION);
|
||||
}
|
||||
|
||||
unittest_teardown()
|
||||
@ -55,11 +56,12 @@ unittest_teardown()
|
||||
|
||||
unittest(test_constants)
|
||||
{
|
||||
assertEqual(ADLER16_MOD_PRIME, 251);
|
||||
assertEqual(ADLER32_MOD_PRIME, 65521);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_adler32)
|
||||
unittest(test_adler_static)
|
||||
{
|
||||
char str1[24] = "abcde";
|
||||
char str2[24] = "abcdef";
|
||||
@ -68,32 +70,10 @@ unittest(test_adler32)
|
||||
assertEqual(96993776, adler32((uint8_t *) str1, 5));
|
||||
assertEqual(136184406, adler32((uint8_t *) str2, 6));
|
||||
assertEqual(234881829, adler32((uint8_t *) str3, 8));
|
||||
}
|
||||
|
||||
|
||||
unittest(test_lorem)
|
||||
{
|
||||
Adler32 ad32;
|
||||
|
||||
ad32.begin();
|
||||
|
||||
fprintf(stderr, "strlen lorem\n");
|
||||
assertEqual(868, strlen(lorem));
|
||||
|
||||
for (int i = 0; lorem[i] != 0; i++)
|
||||
{
|
||||
ad32.add(lorem[i]);
|
||||
}
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
ad32.begin();
|
||||
ad32.add(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
ad32.begin();
|
||||
ad32.addFast(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
assertEqual(57845, adler16((uint8_t *) str1, 5));
|
||||
assertEqual(18016, adler16((uint8_t *) str2, 6));
|
||||
assertEqual(17972, adler16((uint8_t *) str3, 8));
|
||||
}
|
||||
|
||||
|
||||
|
90
libraries/Adler/test/unit_test_Adler16.cpp
Normal file
90
libraries/Adler/test/unit_test_Adler16.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// FILE: unit_test_001.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-01-25
|
||||
// PURPOSE: unit tests for the Adler library
|
||||
// https://github.com/RobTillaart/Adler
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
|
||||
//
|
||||
|
||||
// supported assertions
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/cpp/unittest/Assertion.h#L33-L42
|
||||
// ----------------------------
|
||||
// assertEqual(expected, actual)
|
||||
// assertNotEqual(expected, actual)
|
||||
// assertLess(expected, actual)
|
||||
// assertMore(expected, actual)
|
||||
// assertLessOrEqual(expected, actual)
|
||||
// assertMoreOrEqual(expected, actual)
|
||||
// assertTrue(actual)
|
||||
// assertFalse(actual)
|
||||
// assertNull(actual)
|
||||
// assertNotNull(actual)
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler16.h"
|
||||
|
||||
|
||||
char lorem[] = "Lorem ipsum dolor sit amet, \
|
||||
consectetuer adipiscing elit. Aenean commodo ligula eget dolor. \
|
||||
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient \
|
||||
montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, \
|
||||
pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. \
|
||||
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. \
|
||||
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. \
|
||||
Nullam dictum felis eu pede mollis pretium. Integer tincidunt. \
|
||||
Cras dapibus. Vivamus elementum semper nisi. \
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, \
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, \
|
||||
viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus \
|
||||
varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies \
|
||||
nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "ADLER16_LIB_VERSION: %s\n", (char *) ADLER16_LIB_VERSION);
|
||||
}
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constants)
|
||||
{
|
||||
assertEqual(ADLER16_MOD_PRIME, 251);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ADLER16_lorem)
|
||||
{
|
||||
Adler16 ad16;
|
||||
|
||||
ad16.begin();
|
||||
|
||||
fprintf(stderr, "strlen lorem\n");
|
||||
assertEqual(868, strlen(lorem));
|
||||
|
||||
for (int i = 0; lorem[i] != 0; i++)
|
||||
{
|
||||
ad16.add(lorem[i]);
|
||||
}
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
|
||||
ad16.begin();
|
||||
ad16.add(lorem, strlen(lorem));
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
|
||||
ad16.begin();
|
||||
ad16.addFast(lorem, strlen(lorem));
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
91
libraries/Adler/test/unit_test_Adler32.cpp
Normal file
91
libraries/Adler/test/unit_test_Adler32.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// FILE: unit_test_001.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-01-25
|
||||
// PURPOSE: unit tests for the Adler library
|
||||
// https://github.com/RobTillaart/Adler
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
|
||||
//
|
||||
|
||||
// supported assertions
|
||||
// https://github.com/Arduino-CI/arduino_ci/blob/master/cpp/unittest/Assertion.h#L33-L42
|
||||
// ----------------------------
|
||||
// assertEqual(expected, actual)
|
||||
// assertNotEqual(expected, actual)
|
||||
// assertLess(expected, actual)
|
||||
// assertMore(expected, actual)
|
||||
// assertLessOrEqual(expected, actual)
|
||||
// assertMoreOrEqual(expected, actual)
|
||||
// assertTrue(actual)
|
||||
// assertFalse(actual)
|
||||
// assertNull(actual)
|
||||
// assertNotNull(actual)
|
||||
|
||||
#include <ArduinoUnitTests.h>
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Adler32.h"
|
||||
|
||||
|
||||
char lorem[] = "Lorem ipsum dolor sit amet, \
|
||||
consectetuer adipiscing elit. Aenean commodo ligula eget dolor. \
|
||||
Aenean massa. Cum sociis natoque penatibus et magnis dis parturient \
|
||||
montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, \
|
||||
pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. \
|
||||
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. \
|
||||
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. \
|
||||
Nullam dictum felis eu pede mollis pretium. Integer tincidunt. \
|
||||
Cras dapibus. Vivamus elementum semper nisi. \
|
||||
Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, \
|
||||
consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, \
|
||||
viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus \
|
||||
varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies \
|
||||
nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
|
||||
|
||||
|
||||
unittest_setup()
|
||||
{
|
||||
fprintf(stderr, "ADLER32_LIB_VERSION: %s\n", (char *) ADLER32_LIB_VERSION);
|
||||
}
|
||||
|
||||
unittest_teardown()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constants)
|
||||
{
|
||||
assertEqual(ADLER32_MOD_PRIME, 65521);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ADLER32_lorem)
|
||||
{
|
||||
Adler32 ad32;
|
||||
|
||||
ad32.begin();
|
||||
|
||||
fprintf(stderr, "strlen lorem\n");
|
||||
assertEqual(868, strlen(lorem));
|
||||
|
||||
for (int i = 0; lorem[i] != 0; i++)
|
||||
{
|
||||
ad32.add(lorem[i]);
|
||||
}
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
ad32.begin();
|
||||
ad32.add(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
ad32.begin();
|
||||
ad32.addFast(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
Loading…
x
Reference in New Issue
Block a user