0.1.0 Adler

This commit is contained in:
rob tillaart 2022-01-27 12:18:16 +01:00
parent 6eccb2f585
commit aa47f09b2c
17 changed files with 628 additions and 0 deletions

View File

@ -0,0 +1,14 @@
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
# - due
# - zero
# - leonardo
- m4
- esp32
# - esp8266
# - mega2560
libraries:
- "printHelpers"

View File

@ -0,0 +1,13 @@
name: Arduino-lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update
compliance: strict

View File

@ -0,0 +1,17 @@
---
name: Arduino CI
on: [push, pull_request]
jobs:
runTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb

View File

@ -0,0 +1,18 @@
name: JSON check
on:
push:
paths:
- '**.json'
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:
pattern: "\\.json$"

96
libraries/Adler/Adler.h Normal file
View File

@ -0,0 +1,96 @@
#pragma once
//
// FILE: Adler.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.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
// 0.1.0 2022-01-27 initial version
#include "Arduino.h"
#define ADLER_LIB_VERSION (F("0.1.0"))
const uint16_t ADLER_MOD_PRIME = 65521;
/////////////////////////////////////////////////
//
// STATIC FUNCTION
//
uint32_t adler32(uint8_t *data, uint16_t length)
{
uint32_t s1 = 1;
uint32_t s2 = 0;
for (uint16_t i = 0; i < length;)
{
// if S2 is halfway it is time to do modulo
while ((i < length) && (s2 < 2147483648ULL))
{
s1 += data[i++];
s2 += s1;
}
s1 %= ADLER_MOD_PRIME;
s2 %= ADLER_MOD_PRIME;
}
return (s2 << 16) | s1;
}
/////////////////////////////////////////////////
//
// CLASS VERSION
//
class Adler32
{
public:
Adler32()
{
begin(1, 0);
}
void begin(uint32_t s1 = 1, uint32_t s2 = 0)
{
_s1 = s1;
_s2 = s2;
_count = 0;
}
void add(uint8_t value)
{
_count++;
_s1 += value;
if (_s1 >= ADLER_MOD_PRIME) _s1 -= ADLER_MOD_PRIME;
_s2 += _s1;
if (_s2 >= ADLER_MOD_PRIME) _s2 -= ADLER_MOD_PRIME;
}
void add(uint8_t * array, uint16_t length)
{
while (length--)
{
add(*array++);
}
}
uint32_t getAdler() { return (_s2 << 16) | _s1; };
uint32_t count() { return _count; };
private:
uint32_t _s1;
uint32_t _s2;
uint32_t _count;
};
// -- END OF FILE --

21
libraries/Adler/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022-2022 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

93
libraries/Adler/README.md Normal file
View File

@ -0,0 +1,93 @@
[![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)
[![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)
# Adler
Arduino Library for Adler-32 checksum
## Description
This library provides a Adler checksum of a data array.
Relates to https://github.com/RobTillaart/CRC
Relates to https://github.com/RobTillaart/Fletcher
Tested on Arduino UNO only.
## Interface
## Adler class
Use **\#include "Adler.h"**
- **Adler32()** Constructor, initializes internals.
- **void begin(uint8_t s1 = 1, uint8_t s2 = 0)** resets the internals.
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.
- **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.
The class is typically used for streaming very large blocks of data,
optional with intermediate checksum tests.
#### Performance
Not tested ESP32 (and many other platforms) yet.
First numbers of **.add(value)** measured with test sketch shows the following timing.
| Checksum | UNO 16 MHz | ESP32 240 MHz |
|:------------|:-----------:|:-------------:|
| Adler32 | 5.6 us | |
## Interface static functions
The function is straightforward.
Use **\#include "Adler.h"**
- **uint32_t adler32(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.
#### Performance
Not tested extensively, first numbers of **.add(array, length)**
measured with **Adler_performance.ino** sketch shows the following timing.
Lorem Ipsum text = 868 bytes.
| Checksum | UNO 16 MHz | ESP32 240 MHz |
|:------------|:-----------:|:-------------:|
| Adler32 | 1116 us | |
Average 1116 / 868 = 1.29 us per byte.
## Operation
See examples.
## Future ideas
- test other platforms
- optimize add(array, length) ..

View File

@ -0,0 +1,61 @@
//
// FILE: Adler32_performance.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
#include "Arduino.h"
#include "Adler.h"
Adler32 ad;
volatile uint8_t z;
uint32_t start, stop, randomtime;
void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println();
Serial.println("Adler32_performance");
Serial.print("ADLER_LIB_VERSION: ");
Serial.println(ADLER_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());
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,12 @@
Tested on Arduino UNO
IDE 1.18.19
Adler32_performance
ADLER_LIB_VERSION: 0.1.0
randomtime: 901460
total: 956780
1e4 x add: 55320
checksum: 1607808947

View File

@ -0,0 +1,50 @@
//
// FILE: Adler32_test.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
#include "Arduino.h"
#include "Adler.h"
// expected output
// Adler32_test
// 116982386
// 117310067
// 117047923
Adler32 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("Adler32_test");
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 --

View File

@ -0,0 +1,64 @@
//
// FILE: Adler_performance.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
#include "Arduino.h"
#include "Adler.h"
char str[] = "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.";
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println();
Serial.print("ADLER_LIB_VERSION: ");
Serial.println(ADLER_LIB_VERSION);
for (int i = 0; i < 60; i++)
{
Serial.print(str[i]);
}
Serial.println("...");
uint16_t len = strlen(str);
Serial.print("LENGTH STR: ");
Serial.println(len);
delay(100);
start = micros();
volatile uint16_t x = adler32((uint8_t *) str, len);
stop = micros();
Serial.print("ADLER-32: ");
Serial.print(stop - start);
Serial.print("\t");
Serial.println(x);
delay(100);
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,10 @@
Tested on Arduino UNO
IDE 1.18.19
ADLER_LIB_VERSION: 0.1.0
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ae...
LENGTH STR: 868
ADLER-32: 1116 15516

View File

@ -0,0 +1,46 @@
//
// FILE: Adler_test.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
#include "Arduino.h"
#include "Adler.h"
// expected output
// ADLER_LIB_VERSION: 0.1.0
// 5C801F0
// 81E0256
// E000325
// 11E60398
char str1[24] = "abcde";
char str2[24] = "abcdef";
char str3[24] = "abcdefgh";
char str4[24] = "Wikipedia"; // example from Wikipedia page.
void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println();
Serial.print("ADLER_LIB_VERSION: ");
Serial.println(ADLER_LIB_VERSION);
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);
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,17 @@
# Syntax Colouring Map For ADLER
# Data types (KEYWORD1)
Adler32 KEYWORD1
# Methods and Functions (KEYWORD2)
adler32 KEYWORD2
begin KEYWORD2
add KEYWORD2
getAdler KEYWORD2
count KEYWORD2
# Constants (LITERAL1)
ADLER_LIB_VERSION LITERAL1

View File

@ -0,0 +1,23 @@
{
"name": "Adler",
"keywords": "Adler, checksum",
"description": "Arduino Library for calculating Adler-32 checksum.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/Adler.git"
},
"version": "0.1.0",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",
"headers": "Adler.h"
}

View File

@ -0,0 +1,11 @@
name=Adler
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence="Arduino Library for calculating Adler-32 checksum.
paragraph=
category=Signal Input/Output
url=https://github.com/RobTillaart/Adler
architectures=*
includes=Adler.h
depends=

View File

@ -0,0 +1,62 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2022-01-25
// PURPOSE: unit tests for the GAMMA library
// https://github.com/RobTillaart/GAMMA
// 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 "Adler.h"
unittest_setup()
{
fprintf(stderr, "ADLER_LIB_VERSION: %s\n", (char *) ADLER_LIB_VERSION);
}
unittest_teardown()
{
}
unittest(test_constants)
{
assertEqual(ADLER_MOD_PRIME, 65521);
}
unittest(test_adler32)
{
char str1[24] = "abcde";
char str2[24] = "abcdef";
char str3[24] = "abcdefgh";
assertEqual(96993776, adler32((uint8_t *) str1, 5));
assertEqual(136184406, adler32((uint8_t *) str2, 6));
assertEqual(234881829, adler32((uint8_t *) str3, 8));
}
unittest_main()
// --------