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

4.4 KiB

Arduino CI Arduino-lint JSON check License: MIT GitHub release

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,

  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)