49 lines
1.7 KiB
C++
49 lines
1.7 KiB
C++
#include <stdlib.h>
|
|
|
|
/**
|
|
* Raw memory type used for representing the maximum random size of a value.
|
|
*/
|
|
typedef long unsigned Seed;
|
|
|
|
/**
|
|
* State machine for an instance of XOR shift-based pseudo-random number generation.
|
|
*/
|
|
typedef struct XorShifter {
|
|
/**
|
|
* Initial seed state iniailized when creating the pseudo-random number generator, set by
|
|
* either manually arranging the memory or by calling [CreateXorShifter(seed_t const)]. Every
|
|
* time a new random number is generated, usually by calling
|
|
* [GetXorShifterValue(XorShifter* const, long const, long const)], this value will be mutated
|
|
* with the new iteration value.
|
|
*/
|
|
Seed seed;
|
|
} XorShifter;
|
|
|
|
/**
|
|
* Creates a [XorShifter] with the given `seed` as initial entropy. Note that like all pseudo-
|
|
* random number generators, the initial seed makes all sequential operations deterministic to the
|
|
* value. I.e. running the same program twice with the same seed will yield the same results. To
|
|
* get more entropic values either pass in the current UNIX timestamp value of the device or poll
|
|
* the device's system-dependant entropy device for a new seed each run.
|
|
*/
|
|
XorShifter CreateXorShifter(Seed const seed) {
|
|
return (XorShifter){seed};
|
|
}
|
|
|
|
/**
|
|
* Returns the next pseudo-random iteration in the `xorShifter`'s seeded sequence, reduced down a
|
|
* range between `min` and `max`, provided the `xorShifter`'s seed is greater than `0`.
|
|
*/
|
|
long const GetXorShifterValue(XorShifter* const xorShifter, long const min, long const max) {
|
|
if (xorShifter->seed) {
|
|
Seed value = xorShifter->seed;
|
|
value ^= value << 13;
|
|
value ^= value >> 17;
|
|
value ^= value << 5;
|
|
|
|
return labs((long)(xorShifter->seed = value)) % (labs(max - min) + 1) + min;
|
|
}
|
|
|
|
return 0;
|
|
}
|