0.2.4 Adler

This commit is contained in:
Rob Tillaart 2023-10-16 15:48:37 +02:00
parent 3e39d77414
commit c7b5651fce
21 changed files with 171 additions and 55 deletions

View File

@ -1,7 +1,7 @@
//
// FILE: Adler.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// DATE: 2022-01-27
// PURPOSE: Arduino Library for calculating Adler checksum
// URL: https://github.com/RobTillaart/Adler
@ -23,7 +23,7 @@ uint32_t adler32(uint8_t * array, uint16_t length, uint32_t s1, uint32_t s2)
for (uint16_t i = 0; i < length;)
{
// if _s2 is halfway it is time to do modulo
while ((i < length) && (_s2 < 2147483648ULL)) // MAGIC NR.
while ((i < length) && (_s2 < 2147483648UL)) // MAGIC NUMBER 2^31
{
_s1 += array[i++];
_s2 += _s1;
@ -42,7 +42,7 @@ uint16_t adler16(uint8_t * array, uint16_t length, uint16_t s1, uint16_t s2)
for (uint16_t i = 0; i < length;)
{
// if _s2 is halfway it is time to do modulo
while ((i < length) && (_s2 < 32768)) // MAGIC NR.
while ((i < length) && (_s2 < 32768)) // MAGIC NUMBER 2^15
{
_s1 += array[i++];
_s2 += _s1;
@ -54,5 +54,19 @@ uint16_t adler16(uint8_t * array, uint16_t length, uint16_t s1, uint16_t s2)
}
// char array wrappers
uint32_t adler32(char * array, uint16_t length, uint32_t s1, uint32_t s2)
{
return adler32((uint8_t *) array, length, s1, s2);
}
uint16_t adler16(char * array, uint16_t length, uint16_t s1, uint16_t s2)
{
return adler16((uint8_t *) array, length, s1, s2);
}
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
//
// FILE: Adler.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// 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.3"))
#define ADLER_LIB_VERSION (F("0.2.4"))
const uint32_t ADLER32_MOD_PRIME = 65521;
@ -27,5 +27,9 @@ uint32_t adler32(uint8_t *data, uint16_t length, uint32_t s1 = 1, uint32_t s2 =
uint16_t adler16(uint8_t *data, uint16_t length, uint16_t s1 = 1, uint16_t s2 = 0);
// char array wrappers
uint32_t adler32(char * array, uint16_t length, uint32_t s1 = 1, uint32_t s2 = 0);
uint16_t adler16(char * array, uint16_t length, uint16_t s1 = 1, uint16_t s2 = 0);
// -- END OF FILE --

View File

@ -1,7 +1,7 @@
//
// FILE: Adler16.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// DATE: 2022-06-14
// PURPOSE: Arduino Library for calculating Adler-16 checksum
// URL: https://github.com/RobTillaart/Adler
@ -78,7 +78,7 @@ uint16_t Adler16::addFast(uint8_t * array, uint16_t length)
for (uint16_t i = 0; i < length;)
{
// if S2 is halfway it is time to do modulo
while ((i < length) && (s2 < 32768))
while ((i < length) && (s2 < 32768)) // MAGIC NUMBER 2^15
{
s1 += array[i++];
s2 += s1;
@ -109,7 +109,7 @@ uint16_t Adler16::count()
//////////////////////////////////////////////////////////////
//
// wrappers for strings.
// wrappers for char arrays (strings).
//
void Adler16::add(char value)
{

View File

@ -2,7 +2,7 @@
//
// FILE: Adler16.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// 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.3"))
#define ADLER16_LIB_VERSION (F("0.2.4"))
// largest prime below 2^8
@ -35,7 +35,7 @@ public:
uint16_t addFast(uint8_t * array, uint16_t length);
// wrappers for strings
// wrappers for char array's / strings
void add(char value);
// returns current Adler value
uint16_t add(char * array, uint16_t length);

View File

@ -1,7 +1,7 @@
//
// FILE: Adler32.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// DATE: 2022-01-27
// PURPOSE: Arduino Library for calculating Adler-32 checksum
// URL: https://github.com/RobTillaart/Adler
@ -77,7 +77,7 @@ uint32_t Adler32::addFast(uint8_t * array, uint16_t length)
for (uint16_t i = 0; i < length;)
{
// if S2 is halfway it is time to do modulo
while ((i < length) && (s2 < 2147483648ULL))
while ((i < length) && (s2 < 2147483648UL)) // MAGIC NUMBER 2^31
{
s1 += array[i++];
s2 += s1;
@ -108,7 +108,7 @@ uint32_t Adler32::count()
//////////////////////////////////////////////////////////////
//
// wrappers for strings.
// wrappers for char arrays (strings).
//
void Adler32::add(char value)
{

View File

@ -2,7 +2,7 @@
//
// FILE: Adler.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.3
// VERSION: 0.2.4
// 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.3"))
#define ADLER32_LIB_VERSION (F("0.2.4"))
// largest prime below 2^16
@ -35,7 +35,7 @@ public:
uint32_t addFast(uint8_t * array, uint16_t length);
// wrappers for strings
// wrappers for char array's / strings
void add(char value);
// returns current Adler value
uint32_t add(char * array, uint16_t length);

View File

@ -6,13 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.4] - 2023-10-15
- update readme.md
- add static wrappers for char arrays
- update keywords.txt
- minor edits
## [0.2.3] - 2023-01-16
- update GitHub actions
- update license
- add s1 and s2 parameters to the static functions.
- minor edits
## [0.2.2] - 2022-10-26
- add RP2040 to build-CI

View File

@ -2,8 +2,11 @@
[![Arduino CI](https://github.com/RobTillaart/Adler/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/Adler/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/Adler/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/Adler/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/Adler/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/Adler.svg)](https://github.com/RobTillaart/Adler/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/Adler/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/Adler.svg?maxAge=3600)](https://github.com/RobTillaart/Adler/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/Adler.svg)](https://registry.platformio.org/libraries/robtillaart/Adler)
# Adler
@ -13,10 +16,11 @@ Arduino Library for Adler-32 and experimental Adler-16 checksum.
## Description
This library provides an Adler32 checksum of a data array.
Furthermore since 0.2.0 an experimental Adler16 implementation is added.
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.
This library provides an Adler32 checksum of a data block, typical an array of bytes.
Since 0.2.0 the library also supports an experimental Adler16 implementation.
This Adler16 is often faster as it uses a smaller checksum than the Adler32.
The price is that Adler16 is less sensitive than Adler32 as less possible checksums
are possible.
Still it will have its niches where it will be useful.
0.2.0 is a breaking change, file names have been changed to be more
@ -26,8 +30,9 @@ in line with the CRC library.
- Adler16.h for the Adler16 class.
#### related
#### Related
- https://en.wikipedia.org/wiki/Adler-32
- https://github.com/RobTillaart/Adler
- https://github.com/RobTillaart/CRC
- https://github.com/RobTillaart/Fletcher
@ -44,18 +49,22 @@ Tested on Arduino UNO and ESP32.
### Adler class
Use **\#include "Adler32.h"** or **\#include "Adler16.h"**
```cpp
#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.
- **void begin(uint32_t s1 = 1, uint32_t s2 = 0)** resets the internals.
optional setting start values for s1 and s2. Note this is not part of the standard.
These parameters allows a restart from a specific index in a buffer.
- **void add(uint8_t value)** add a single value to the checksum.
- **uint32_t add(const uint8_t \* array, uint8_t length)** add an array of values to the checksum.
- **uint32_t add(uint8_t \* array, uint16_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.
- **uint32_t addFast(uint8_t \* array, uint16_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.
@ -65,6 +74,12 @@ can overflow without affecting checksum.
The class is typically used for streaming very large blocks of data,
optional with intermediate checksum tests (e.g after every 256 bytes)
Wrappers exist for adding char and char array. Functional identical to above.
- **void add(char value)**
- **uint32_t add(char \* array, uint16_t length)**
- **uint32_t addFast(char \* array, uint16_t length)**
## Performance Adler32
@ -170,16 +185,23 @@ doing the modulo more often.
## Interface static functions
The functions are straightforward.
```cpp
#include "Adler.h"
```
Use **\#include "Adler.h"**
- **uint32_t adler32(uint8_t \*data, uint16_t length, uint32_t s1 = 1, uint32_t s2 = 0)** length in units of 1 byte = 8 bits.
- **uint16_t adler16(uint8_t \*data, uint16_t length, uint16_t s1 = 1, uint16_t s2 = 0)** length in units of 1 byte = 8 bits.
The functions are typically used for an in memory buffer to calculate the checksum once.
The static 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.
The functions are straightforward. Length is in bytes (8 bits).
- **uint32_t adler32(uint8_t \*data, uint16_t length, uint32_t s1 = 1, uint32_t s2 = 0)**
- **uint16_t adler16(uint8_t \*data, uint16_t length, uint16_t s1 = 1, uint16_t s2 = 0)**
Two wrapper functions added in 0.2.4 for char array's (convenience).
- **uint32_t adler32(char \*data, uint16_t length, uint32_t s1 = 1, uint32_t s2 = 0)**
- **uint16_t adler16(char \*data, uint16_t length, uint16_t s1 = 1, uint16_t s2 = 0)**
### Performance
@ -226,8 +248,8 @@ See examples.
- next major upgrade(0.3.0)
- other platforms?
- extend unit tests
- s1 s2 param static functions
-
- s1 s2 parameter static functions
#### Could
@ -237,8 +259,7 @@ See examples.
- max uint32_t prime = 4.294.967.291
- need printHelpers library for printing.
- only on request.
- wrapper functions (static) for char array's in adler.h ?
- fix MAGIC NRS in adler.cpp
- **void add(String str);**?
#### Wont
@ -249,4 +270,11 @@ See examples.
- would create too much overhead for repeated calls.
## Support
If you appreciate my libraries, you can support the development and maintenance.
Improve the quality of the libraries by providing issues and Pull Requests, or
donate through PayPal or GitHub sponsors.
Thank you,

View File

@ -177,3 +177,4 @@ void loop()
// -- END OF FILE --

View File

@ -31,6 +31,7 @@ void setup()
while (!Serial);
Serial.println();
Serial.println(__FILE__);
Serial.print("ADLER_LIB_VERSION: ");
Serial.println(ADLER_LIB_VERSION);
@ -76,3 +77,4 @@ void loop()
// -- END OF FILE --

View File

@ -0,0 +1,14 @@
Tested on Arduino UNO
IDE 1.18.19
D:\Rob\WORK\Arduino\libraries\Adler\examples\Adler_performance\Adler_performance.ino
ADLER_LIB_VERSION: 0.2.4
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ae...
LENGTH STR: 868
TIME us: 1116
ADLER-32: 3972480156 ECC73C9C
TIME us: 1740
ADLER-16: 57303 DFD7

View File

@ -35,6 +35,7 @@ void setup()
while (!Serial);
Serial.println();
Serial.println(__FILE__);
Serial.print("ADLER_LIB_VERSION: ");
Serial.println(ADLER_LIB_VERSION);
Serial.println();
@ -50,6 +51,18 @@ void setup()
Serial.println(adler32((uint8_t *) str3, 8), HEX);
Serial.println(adler32((uint8_t *) str4, 9), HEX);
Serial.println();
Serial.println(adler16(str1, 5), HEX);
Serial.println(adler16(str2, 6), HEX);
Serial.println(adler16(str3, 8), HEX);
Serial.println(adler16(str4, 9), HEX);
Serial.println();
Serial.println(adler32(str1, 5), HEX);
Serial.println(adler32(str2, 6), HEX);
Serial.println(adler32(str3, 8), HEX);
Serial.println(adler32(str4, 9), HEX);
Serial.println();
}

View File

@ -0,0 +1,23 @@
D:\Rob\WORK\Arduino\libraries\Adler\examples\Adler_test\Adler_test.ino
ADLER_LIB_VERSION: 0.2.4
E1F5
4660
4634
40A7
5C801F0
81E0256
E000325
11E60398
E1F5
4660
4634
40A7
5C801F0
81E0256
E000325
11E60398

View File

@ -1,6 +1,7 @@
# Syntax Colouring Map For ADLER
# Data types (KEYWORD1)
Adler KEYWORD1
Adler32 KEYWORD1
Adler16 KEYWORD1
@ -8,9 +9,11 @@ Adler16 KEYWORD1
# Methods and Functions (KEYWORD2)
adler32 KEYWORD2
adler16 KEYWORD2
begin KEYWORD2
add KEYWORD2
addFast KEYWORD2
getAdler KEYWORD2
count KEYWORD2

View File

@ -1,7 +1,7 @@
{
"name": "Adler",
"keywords": "Adler32, Adler16, checksum",
"description": "Arduino Library for calculating Adler-32 checksum.",
"description": "Arduino Library for calculating Adler-32 and Adler-16 checksum.",
"authors":
[
{
@ -15,9 +15,9 @@
"type": "git",
"url": "https://github.com/RobTillaart/Adler.git"
},
"version": "0.2.3",
"version": "0.2.4",
"license": "MIT",
"frameworks": "arduino",
"frameworks": "*",
"platforms": "*",
"headers": "Adler.h"
}

View File

@ -1,5 +1,5 @@
name=Adler
version=0.2.3
version=0.2.4
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.

View File

@ -75,6 +75,14 @@ unittest(test_adler_static)
assertEqual(57845, adler16((uint8_t *) str1, 5));
assertEqual(18016, adler16((uint8_t *) str2, 6));
assertEqual(17972, adler16((uint8_t *) str3, 8));
assertEqual(96993776, adler32(str1, 5));
assertEqual(136184406, adler32(str2, 6));
assertEqual(234881829, adler32(str3, 8));
assertEqual(57845, adler16(str1, 5));
assertEqual(18016, adler16(str2, 6));
assertEqual(17972, adler16(str3, 8));
}