GY-63_MS5611/libraries/DEVRANDOM/README.md
2022-10-31 19:50:00 +01:00

120 lines
4.4 KiB
Markdown

[![Arduino CI](https://github.com/RobTillaart/DEVRANDOM/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/DEVRANDOM/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/DEVRANDOM/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/DEVRANDOM/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/DEVRANDOM/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/DEVRANDOM/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/DEVRANDOM.svg?maxAge=3600)](https://github.com/RobTillaart/DEVRANDOM/releases)
# DEVRANDOM
Arduino library to wrap a random generator in a stream.
## Description
The library implements a stream class that mimics the /dev/random
device of a Linux system. It can be used for testing with streams.
## Interface
### Constructor
- **DEVRANDOM()** Constructor.
- **DEVRANDOM(char \* str)** Constructor, seeding with a string of characters.
- **DEVRANDOM(uint32_t value)** Constructor, seeding with a integer value.
- **DEVRANDOM(float value)** Constructor, seeding with a float value.
### Streeam interface
To read and to reseed the random generator.
- **int available()** There is always 1 next byte available.
- **int peek()** will give you next byte.
- **int read()** will give you next byte and generate a new one.
- **size_t write(uint8_t data)** data will be used for reseeding the random number generator (RNG), mode 0 and 3.
In digitalRead and analogRead mode the seed is used to XOR
the value, so it does have some effect.
- **size_t write(uint8_t \* buffer, size_t size)** speeds up reseeding
for some print / println calls.
- **void flush()** to keep the CI happy.
As **write()** reseeds the RNG, printing to **DEVRANDOM** will also reseed the RNG.
E.g. **dr.println("Hello world");** or **dr.println(3.45678);** will reseed DEVRANDOM too.
See examples.
If footprint is an issue one could remove the **size_t write(uint8_t \* buffer, size_t size)**
from the library and implement a stripped version in **write()**.
Reseeding will become slower but as reseeding is not used that often
this might be a good trade off.
### Random generator selection
- **void useRandom()** use the build in software random number generator. This is the default, but platform dependant.
- **void useDigitalRead(uint8_t pin)** use digitalRead to read 8 bits from a defined pin.
One can build a hardware RNG that flips between 0 and 1 very rapidly and unpredictably.
Connect this signal to the pin and it will be read and generate a random byte.
The seed value from the write is used as an XOR byte.
- **void useAnalogRead(uint8_t pin)** use the analogRead to read 8 bits
This can be fed with any analogue noise source.
The seed value from the write is used as a XOR byte.
- **void useMarsaglia()** uses the Marsaglia pseudo random generator.
This one is quite fast and good, and more important portable.
- **uint8_t getMode()** returns the source of randomness.
| Mode | DEVRANDOM_MODE | Type |
|:-------:|:----------------:|:-----------------------|
| 0 | build in random | depends on platform |
| 1 | digitalRead | hardware external |
| 2 | analogRead | hardware external |
| 3 | Marsaglia | software portable PRNG |
There might be other RNG's in the future.
If you have an interesting and fast PRNG to be included please let me know.
### Obsolete
- **useSW()** replaced by **useRandom()**.
- **useHW(uint8_t pin)** replaced by **useDigitalRead()**.
- **useAR(uint8_t pin)** replaced by **useAnalogRead()**.
## Operation
See example sketches.
### Example
As shown in the example one can use fscanf() to read larger data types,
```cpp
DEVRANDOM dr;
uint32_t x;
fscanf((FILE*) &dr, "%lu", &x);
Serial.println(x);
```
However float is not supported standard in the fscanf() by UNO and strings (%s) generate garbage.
So a password generator is a bit more difficult (and a good exercise).
## Future
- improve documentation.
- add examples.
- add other (portable) PRNG.
- **available()** returns 1,
- should that be more e.g. INT_MAX
- a random number > 0 ?
- ?
- when changing mode should \_next == **peek()** be reset?
- yes, think so ```_next = _rnd();```
- when already in that mode? (=> complex)