mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
120 lines
4.4 KiB
Markdown
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)
|
|
|