mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.1 Adler
This commit is contained in:
parent
3d74747999
commit
580182c3ad
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: Adler.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: Adler.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
@ -12,7 +12,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER_LIB_VERSION (F("0.2.0"))
|
||||
#define ADLER_LIB_VERSION (F("0.2.1"))
|
||||
|
||||
|
||||
const uint32_t ADLER32_MOD_PRIME = 65521;
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: Adler16.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-06-14
|
||||
// PURPOSE: Arduino Library for calculating Adler-16 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
@ -56,13 +56,14 @@ void Adler16::add(uint8_t value)
|
||||
|
||||
// straightforward going through the array.
|
||||
// small footprint
|
||||
void Adler16::add(uint8_t * array, uint16_t length)
|
||||
// returns current Adler value
|
||||
uint16_t Adler16::add(uint8_t * array, uint16_t length)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
add(*array++);
|
||||
}
|
||||
return;
|
||||
return (_s2 << 8) | _s1;
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +72,8 @@ void Adler16::add(uint8_t * array, uint16_t length)
|
||||
// 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)
|
||||
// returns current Adler value
|
||||
uint16_t Adler16::addFast(uint8_t * array, uint16_t length)
|
||||
{
|
||||
_count += length;
|
||||
uint16_t s1 = _s1;
|
||||
@ -92,6 +94,7 @@ void Adler16::addFast(uint8_t * array, uint16_t length)
|
||||
}
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
return (s2 << 8) | s1;
|
||||
}
|
||||
|
||||
|
||||
@ -101,6 +104,12 @@ uint16_t Adler16::getAdler()
|
||||
};
|
||||
|
||||
|
||||
uint16_t Adler16::count()
|
||||
{
|
||||
return _count;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// wrappers for strings.
|
||||
@ -111,15 +120,15 @@ void Adler16::add(char value)
|
||||
}
|
||||
|
||||
|
||||
void Adler16::add(char * array, uint16_t length)
|
||||
uint16_t Adler16::add(char * array, uint16_t length)
|
||||
{
|
||||
add((uint8_t *) array, length);
|
||||
return add((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
void Adler16::addFast(char * array, uint16_t length)
|
||||
uint16_t Adler16::addFast(char * array, uint16_t length)
|
||||
{
|
||||
addFast((uint8_t *) array, length);
|
||||
return addFast((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: Adler16.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-06-15
|
||||
// PURPOSE: Arduino Library for calculating Adler-16 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
@ -13,7 +13,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER16_LIB_VERSION (F("0.2.0"))
|
||||
#define ADLER16_LIB_VERSION (F("0.2.1"))
|
||||
|
||||
|
||||
// largest prime below 2^8
|
||||
@ -24,21 +24,25 @@ class Adler16
|
||||
public:
|
||||
Adler16();
|
||||
|
||||
void begin(uint16_t s1 = 1, uint16_t s2 = 0);
|
||||
void begin(uint16_t s1 = 1, uint16_t s2 = 0);
|
||||
|
||||
void add(uint8_t value);
|
||||
void add(uint8_t * array, uint16_t length);
|
||||
void add(uint8_t value);
|
||||
// returns current Adler value
|
||||
uint16_t add(uint8_t * array, uint16_t length);
|
||||
// trade PROGMEM for speed
|
||||
void addFast(uint8_t * array, uint16_t length);
|
||||
// returns current Adler value
|
||||
uint16_t 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);
|
||||
|
||||
void add(char value);
|
||||
// returns current Adler value
|
||||
uint16_t add(char * array, uint16_t length);
|
||||
// returns current Adler value
|
||||
uint16_t addFast(char * array, uint16_t length);
|
||||
|
||||
// returns current Adler value
|
||||
uint16_t getAdler();
|
||||
uint16_t count() { return _count; };
|
||||
uint16_t count();
|
||||
|
||||
private:
|
||||
uint16_t _s1;
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: Adler32.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
@ -55,13 +55,14 @@ void Adler32::add(uint8_t value)
|
||||
|
||||
// straightforward going through the array.
|
||||
// small footprint.
|
||||
void Adler32::add(uint8_t * array, uint16_t length)
|
||||
// returns current Adler value
|
||||
uint32_t Adler32::add(uint8_t * array, uint16_t length)
|
||||
{
|
||||
while (length--)
|
||||
{
|
||||
add(*array++);
|
||||
}
|
||||
return;
|
||||
return (_s2 << 16) | _s1;
|
||||
}
|
||||
|
||||
|
||||
@ -70,7 +71,8 @@ void Adler32::add(uint8_t * array, uint16_t length)
|
||||
// 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)
|
||||
// returns current Adler value
|
||||
uint32_t Adler32::addFast(uint8_t * array, uint16_t length)
|
||||
{
|
||||
_count += length;
|
||||
uint32_t s1 = _s1;
|
||||
@ -91,6 +93,7 @@ void Adler32::addFast(uint8_t * array, uint16_t length)
|
||||
}
|
||||
_s1 = s1;
|
||||
_s2 = s2;
|
||||
return (s2 << 16) | s1;
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +103,11 @@ uint32_t Adler32::getAdler()
|
||||
};
|
||||
|
||||
|
||||
uint32_t Adler32::count()
|
||||
{
|
||||
return _count;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -111,15 +119,15 @@ void Adler32::add(char value)
|
||||
}
|
||||
|
||||
|
||||
void Adler32::add(char * array, uint16_t length)
|
||||
uint32_t Adler32::add(char * array, uint16_t length)
|
||||
{
|
||||
add((uint8_t *) array, length);
|
||||
return add((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
void Adler32::addFast(char * array, uint16_t length)
|
||||
uint32_t Adler32::addFast(char * array, uint16_t length)
|
||||
{
|
||||
addFast((uint8_t *) array, length);
|
||||
return addFast((uint8_t *) array, length);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: Adler.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// DATE: 2022-01-27
|
||||
// PURPOSE: Arduino Library for calculating Adler-32 checksum
|
||||
// URL: https://github.com/RobTillaart/Adler
|
||||
@ -12,7 +12,7 @@
|
||||
#include "Arduino.h"
|
||||
|
||||
|
||||
#define ADLER32_LIB_VERSION (F("0.2.0"))
|
||||
#define ADLER32_LIB_VERSION (F("0.2.1"))
|
||||
|
||||
|
||||
// largest prime below 2^16
|
||||
@ -24,21 +24,25 @@ class Adler32
|
||||
public:
|
||||
Adler32();
|
||||
|
||||
void begin(uint32_t s1 = 1, uint32_t s2 = 0);
|
||||
void begin(uint32_t s1 = 1, uint32_t s2 = 0);
|
||||
|
||||
void add(uint8_t value);
|
||||
void add(uint8_t * array, uint16_t length);
|
||||
void add(uint8_t value);
|
||||
// returns current Adler value
|
||||
uint32_t add(uint8_t * array, uint16_t length);
|
||||
// trade PROGMEM for speed
|
||||
void addFast(uint8_t * array, uint16_t length);
|
||||
// returns current Adler value
|
||||
uint32_t 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);
|
||||
void add(char value);
|
||||
// returns current Adler value
|
||||
uint32_t add(char * array, uint16_t length);
|
||||
// returns current Adler value
|
||||
uint32_t addFast(char * array, uint16_t length);
|
||||
|
||||
|
||||
uint32_t getAdler();
|
||||
uint32_t count() { return _count; };
|
||||
uint32_t count();
|
||||
|
||||
private:
|
||||
uint32_t _s1;
|
||||
|
@ -5,6 +5,13 @@ 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.1] - 2022-09-20
|
||||
|
||||
- return value added to **add(array)**
|
||||
- return value added to **addFast(array, length)**
|
||||
- update documentation (e.g. timing table).
|
||||
- moved count() to .cpp
|
||||
|
||||
## [0.2.0] - 2022-06-15
|
||||
|
||||
- breaking change
|
||||
|
@ -15,9 +15,9 @@ Arduino Library for Adler-32 and experimental Adler-16 checksum.
|
||||
|
||||
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.
|
||||
This one is often faster as it uses a smaller checksum than the Adler32.
|
||||
The price is that Adler16 is less sensitive than the Adler32.
|
||||
Still it will have its niches where it will be useful.
|
||||
|
||||
Relates to https://github.com/RobTillaart/CRC
|
||||
|
||||
@ -46,10 +46,14 @@ The interface for the Adler16 is very similar.
|
||||
optional setting start values for s1 and s2. Note this is not part of the standard.
|
||||
This allows a restart from a specific index in a buffer.
|
||||
- **void add(uint8_t value)** add a single value to the checksum.
|
||||
- **void add(const uint8_t \* array, uint8_t length)** add an array of values to the checksum.
|
||||
- **void addFast(const uint8_t \* array, uint8_t length)** add an array of values to the checksum. Is faster by trading PROGMEM for performance.
|
||||
- **uint32_t add(const uint8_t \* array, uint8_t length)** add an array of values to the checksum.
|
||||
Returns the current checksum.
|
||||
- **uint32_t addFast(const uint8_t \* array, uint8_t length)** add an array of values to the checksum.
|
||||
Is faster by trading PROGMEM for performance.
|
||||
Returns the current checksum.
|
||||
- **uint32_t getAdler()** get the current checksum.
|
||||
- **uint32_t count()** get the number of items added. Merely a debugging feature, can overflow without affecting checksum.
|
||||
- **uint32_t count()** get the number of items added. Merely a debugging feature,
|
||||
can overflow without affecting checksum.
|
||||
|
||||
The class is typically used for streaming very large blocks of data,
|
||||
optional with intermediate checksum tests.
|
||||
@ -57,7 +61,8 @@ optional with intermediate checksum tests.
|
||||
|
||||
## Performance Adler32
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
Only tested on UNO and ESP32 yet.
|
||||
If you have data of other platforms, please let me know.
|
||||
|
||||
Numbers measured with **Adler32_performance.ino**.
|
||||
|
||||
@ -69,9 +74,9 @@ instead of a modulo.
|
||||
|
||||
| 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 | |
|
||||
| 0.1.0 | add | 5.6 us | |
|
||||
| 0.1.2 | add | 6.6 us | |
|
||||
| 0.2.0 | add | 5.9 us | 1.7 us |
|
||||
|
||||
|
||||
### add(lorem) 868 chars
|
||||
@ -81,9 +86,10 @@ 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 | |
|
||||
| 0.1.0 | add | | |
|
||||
| 0.1.2 | add | 6392 us | |
|
||||
| 0.2.0 | add | 5748 us | 145 us |
|
||||
|
||||
|
||||
Note: **add()** is about 6.6 us per byte.
|
||||
|
||||
@ -91,7 +97,7 @@ 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.
|
||||
reference **add(array, length)** and uses 108 bytes more (UNO).
|
||||
So the function has a larger footprint.
|
||||
Depending on your needs, choose performance or footprint.
|
||||
|
||||
@ -102,15 +108,15 @@ See **Adler32_performance_addFast.ino**
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | addFast | | |
|
||||
| 0.1.2 | addFast | 1348 us | |
|
||||
| 0.2.0 | addFast | 1348 us | |
|
||||
| 0.2.0 | addFast | 1348 us | 66 us |
|
||||
|
||||
Note: **addFast()** is less than 2 us per byte.
|
||||
|
||||
|
||||
|
||||
## Performance Adler16
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
Only tested on UNO and ESP32 yet.
|
||||
If you have data of other platforms, please let me know.
|
||||
|
||||
Numbers measured with **Adler16_performance.ino**.
|
||||
|
||||
@ -122,7 +128,7 @@ instead of a modulo.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | add | 4.0 us | |
|
||||
| 0.2.0 | add | 4.0 us | 1.8 us |
|
||||
|
||||
The per byte performance of the Adler16 (on UNO) is faster
|
||||
than the Adler32 **add(value)**. The reason is that a 16 bit
|
||||
@ -136,7 +142,7 @@ over the array and has a small footprint.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | add | 4040 us | |
|
||||
| 0.2.0 | add | 4040 us | 160 us |
|
||||
|
||||
Note: **add()** is about 6.6 us per byte.
|
||||
|
||||
@ -148,7 +154,7 @@ reference **add(array, length)**.
|
||||
|
||||
| Version | Function | UNO 16 MHz | ESP32 240 MHz |
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.2.0 | addFast | 1968 us | |
|
||||
| 0.2.0 | addFast | 1968 us | 79 us |
|
||||
|
||||
The gain of the faster 16 bit modulo meets the frequency of
|
||||
doing the modulo more often.
|
||||
@ -169,7 +175,8 @@ Think of packets in a network, records in a database, or a checksum for an confi
|
||||
|
||||
### Performance
|
||||
|
||||
Not tested ESP32 (and many other platforms) yet.
|
||||
Only tested on UNO and ESP32 yet.
|
||||
If you have data of other platforms, please let me know.
|
||||
|
||||
Numbers measured with **Adler_performance.ino**.
|
||||
|
||||
@ -179,18 +186,20 @@ Lorem Ipsum text = 868 bytes.
|
||||
|:-------:|:---------|:----------:|:-------------:|
|
||||
| 0.1.0 | Adler32 | 1116 us | |
|
||||
| 0.1.2 | Adler32 | 1116 us | |
|
||||
| 0.2.0 | Adler32 | 1116 us | |
|
||||
| 0.2.0 | Adler16 | 1736 us | |
|
||||
| 0.2.0 | Adler32 | 1116 us | 60 us |
|
||||
| 0.2.0 | Adler16 | 1736 us | 75 us |
|
||||
|
||||
|
||||
#### UNO
|
||||
|
||||
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.
|
||||
As the Adler16 is less performant as the Adler32 (on all tested platforms),
|
||||
it is often the best to use the 32 bit version.
|
||||
|
||||
|
||||
## Operation
|
||||
@ -200,17 +209,20 @@ See examples.
|
||||
|
||||
## Future
|
||||
|
||||
- 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)
|
||||
- would need a large prime (which) => 4294967291
|
||||
- max uint32_t = 4.294.967.296
|
||||
- max uint32_t prime = 4.294.967.291
|
||||
- need printHelpers library for printing.
|
||||
- only on request.
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
- do the string wrappers need strlen() ? parameter.
|
||||
- yes, as string can be processed partially.
|
||||
- no return value for **add(value)**
|
||||
- would create too much overhead for repeated calls.
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
Adler32_performance
|
||||
ADLER32_LIB_VERSION: 0.2.0
|
||||
randomtime: 6949
|
||||
total: 8639
|
||||
1e4 x add: 1690
|
||||
checksum: 2580568639
|
||||
|
||||
total: 224706
|
||||
1e6 x add: 217757
|
||||
checksum: 237492440
|
||||
|
||||
LENGTH LOREM: 868
|
||||
|
||||
lorem 1: 198 checksum: 3972480156
|
||||
lorem 2: 145 checksum: 3972480156
|
||||
lorem 3: 66 checksum: 3972480156
|
||||
|
||||
LENGTH HELLO: 11
|
||||
|
||||
hello 1: 3 checksum: 436929629
|
||||
hello 2: 3 checksum: 436929629
|
||||
hello 3: 3 checksum: 436929629
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/Adler.git"
|
||||
},
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=Adler
|
||||
version=0.2.0
|
||||
version=0.2.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino Library for calculating Adler-32 and Adler-16 checksum.
|
||||
|
@ -74,14 +74,17 @@ unittest(test_ADLER16_lorem)
|
||||
ad16.add(lorem[i]);
|
||||
}
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
assertEqual(868, ad16.count());
|
||||
|
||||
ad16.begin();
|
||||
ad16.add(lorem, strlen(lorem));
|
||||
assertEqual(57303, ad16.add(lorem, strlen(lorem)));
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
assertEqual(868, ad16.count());
|
||||
|
||||
ad16.begin();
|
||||
ad16.addFast(lorem, strlen(lorem));
|
||||
assertEqual(57303, ad16.addFast(lorem, strlen(lorem)));
|
||||
assertEqual(57303, ad16.getAdler());
|
||||
assertEqual(868, ad16.count());
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,15 +74,17 @@ unittest(test_ADLER32_lorem)
|
||||
ad32.add(lorem[i]);
|
||||
}
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
assertEqual(868, ad32.count());
|
||||
|
||||
ad32.begin();
|
||||
ad32.add(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.add(lorem, strlen(lorem)));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
assertEqual(868, ad32.count());
|
||||
|
||||
ad32.begin();
|
||||
ad32.addFast(lorem, strlen(lorem));
|
||||
assertEqual(3972480156, ad32.addFast(lorem, strlen(lorem)));
|
||||
assertEqual(3972480156, ad32.getAdler());
|
||||
|
||||
assertEqual(868, ad32.count());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user