PractRand offers several closely related interfaces to RNGs. The interface types are: 1. Polymorphic RNGs 2. Light-weight RNGs 3. Raw RNGs 4. Entropy Pools (which are RNGs that can accumulate entropy) 5. Non-recommended RNGs (aka other RNGs) 1. Polymorphic RNGs: A polymorphic RNG supports the full standard PractRand RNG interface. And, as the name implies they are polymorphic - they have a vtable, so you can use base class pointers to point to any polymorphic RNG. In addition to the methods of the standard PractRand RNG interface, polymorphic RNGs also have a number of methods that are optional extensions that most RNG algorithms do not support. These are present in the interface for all Polymorphic RNGs in order to simplify inheritance. On RNGs that do not support them, calling them has no effect. Every RNG in PractRand is available in a Polymorphic form. The base class for Polymorphic RNGs is PractRand::vRNG (for virtual RNG). The same class is also known under several aliases: PractRand::RNGs::vRNG PractRand::RNGs::PolymorphicRNGs::vRNG Polymorphic RNGs are in the PractRand::RNGs::Polymorphic namespace. 2. Light-weight RNGs: Polymorphic RNGs are slower and larger than they strictly need to be, in order to allow them to be polymorphic. If those costs are too high, the suggested alternative is a light-weight RNG, which is basically the same thing only without polymorphism. Light-weight RNGs are in the PractRand::RNGs::LightWeight namespace. 3. Raw RNGs: A raw RNG is the minimal type necessary to define an RNG algorithm. They define the mandatory stuff - state variables, core algorithm, a small amount of metadata, and optionally anything else specific to the algorithm (custom seeding methods, etc). But they do not provide a nice interface, just a small subset of the normal PractRand RNG interface. Normally users will not use raw RNGs directly. However, it is possible if you desire to do so for some reason. Raw RNGs are in the PractRand::RNGs::Raw namespace. 4. Entropy-accumulating RNGs: Convential RNGs have a single simple seeding process - you give them a seed, then they are seeded. Entropy-accumulating RNGs, called "entropy pools" in PractRand, have the ability to support more complex seeding practices. The special characteristics of an entropy pool are: A. Entropy Pools in PractRand all have default constructors. The default constructors effectively seed them to a specific predefined state. B. Entropy Pools in PractRand have a set of methods of the form add_entropy*. These include add_entropy8, add_entropy16, add_entropy32, add_entropy64, add_entropy_N, and, on polymorphic Entropy Pools, add_entropy_automatically(). Each of these methods performs basically a progressive seeding - that is, the Entropy Pool changes to a new state that is dependent upon an entropic function of the old state and the value passed to add_entropy*. Thus, the output of an Entropy Pool is functionally a hash of the initial seed of the entropy pool, all values passed to add_entropy*, the number (and possibly type) of outputs requested so far, and possibly the order in which the outputs were requested relative to when the entropy was added and when flush_buffers() was called. C. Entropy Pools have a method flush_buffers(). On an entropy pool, after adding entropy with add_entropy* calls as described above you must call flush_buffers(), otherwise the entropy added may just wait in a buffer somewhere indefinitely without effecting the output, or might not be thoroughly mixed in to the state. For more information about entropy pools, see RNG_entropy_pools.txt 5. Non-recommended RNGs (aka other RNGs) These RNGs are intended only for use in testing - they are chosen for their flaws, not their lack of flaws. They are used when attempting to determine how wide a variety of flaws a statistical test can find, and how quickly. They are needed because most of the recommended RNGs in PractRand do not fail any known statistical tests, and even the ones that do often take a long time. They are technically Polymorphic RNGs, but they have no constructors. Effectively they always act like a polymorphic RNG seeded with PractRand::SEED_NONE. This is to minimize the amount of code needed for each one, so that it's very easy to add more of them.