Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've used
#include<stdlib>
#include<time>
using namespace std;
srand((unsigned)time(0));
int n=(rand()>>8)%4;
but what other random functions are there, or what other function could be used as random number generators?
EDIT: I don't really have a particular reason for asking this question, I just wanted to know if C++ had any other random functions.
Boost Random Number Library offers a broad range of generators (quality vs performance) and some typical random distributions. Everything rather nice and straightforward to use.
If you want some other methods/libraries - then google for cryptographic random numbers, also you can use this document as a reference.
Don't invent your own solutions unless you are an expert/researcher in the field/etc, take advantage of already existing solutions which were usually written by Smart People, and thoroughly examined by other Smart People.
The rand() and srand() functions are all the C++ Standard specifies. And if it comes to writing your own, be aware of what John von Neumann said:
"Anyone who considers arithmetical
methods of producing random digits is
of course in a state of sin"
This code is pretty efficient. Although users may begin to notice a pattern after a few iterations.
int FastRandom()
{
return 10;
}
Not strictly C++, but Windows specific:
CryptGenRandom
I'm sure all operating systems have their equivalent cryptographically secure random generator functions.
int unixrand()
{
int x;
int f = open("/dev/random", O_RDONLY);
if (f < 0) return -1; /* Error */
if (sizeof(x) != read(f, &x, sizeof(x))) {
close(f);
return -1;
}
close(f);
if (x < 0) x = ~x;
return x;
}
(Cross-posting from an answer I just wrote to a similar question)
Have a look at ISAAC (Indirection, Shift, Accumulate, Add, and Count). Its uniformly distributed and has an average cycle length of 2^8295.
It's fast too, since it doesnt involve multiplication or modulus.
Bruce Schneier and John Kelsey wrote a random number generator you may be interested in. Rather, it's a seed generator. Even though Yarrow is no longer supported, you may be interested in how it gathers entropy.
OpenSSL has an API that is relatively easy to access and pretty portable. And Mozilla comes with a decent API that wraps whatever the OS offers.
Personally, though, I generally use Boost.Random, which was already suggested.
Random gives you a good random number at uniform distribution and does a pretty good job at that.
Anything else would mean that you want to actually skew the distribution.
For example, using Microsoft's GUIDs generator would give you a random id that is less likely to be repeated and takes into account things like time and computer.
Time is usually the most random operation that is also cheap to perform, but it's still possible to predict.
If you want true randomness, using some kind of external input is your only solution.
Quantum Random Bit Generator is one service that provides such data.
Related
I am working on a secure LoRa transmission, where I need to generate the same pseudo-random number on the transmitter and the receiver (it would be part of the encryption algorithm) based on an input counter. So this function should give the same output for a given input, just like a hashing algorithm.
As an example here is what I mean, but as you can see the computation gets longer based on the input:
unsigned int f(unsigned int input) {
srand(1234);
for (unsigned int i = 0; i < input; i++) {
rand();
}
return rand();
}
Is there a more efficient way to do this? I am on an ESP32 microcontroller.
edit. Thanks for all the answers. I could have accomplished what I was trying to do with a CRC function, but as per your recommendation I ended up ditching this approach and used a standard encryption algorithm instead.
You should not use rand for this purpose as it is implementation-defined which presents a couple of issues for your use-case:
It may produce different numbers on different targets
It is not guaranteed to be cryptographically secure
What you describe is a cryptographic hash function. There are many libraries available which offer these. Generally there is a trade-off between security and performance, so you will have to select one.
it would be part of the encryption algorithm
If the application must be truly secure, I would recommend using an existing algorithm such as AES rather than trying to write your own, as it appears you are trying to do here. Again, these are available as libraries, some of which are small and suitable for embedded systems such as tiny-AES.
Here a nice question arose today, presenting standard functions for random generation: Get the state (seed) of a distribution of random numbers
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Whenever we want to pick a random number from a vector we use a method called rand(). I want to know how it works from the backend.
rand has a seed value - e.g. setting it to the current time...
srand( time(NULL ) ); // second good enough
Then there is some math such as this....
unsigned int seed; // set by srand
unsigned int rand() {
seed = seed * number + offset;
return seed;
}
The number and offset are chosen, so the whole of the range of `unsigned int are covered. This generally means some form of prime number.
As mentioned in the comments, this is a very complex area.
If srand is not called, then seed has an initial value, which means that (ignoring thread timing issues), your program will get the same results each time it is run.
Getting the same results is handy for re-running tests, but problematic if it is say a game logic.
There is no "back-end" involved for rand.
BTW, in C++ you'll better use <random> standard header and related utilities, which are in the C++ standard library.
The rand function is part of the C standard library. It is unrelated to C++ vectors.
They (both the rand function and utilities from <random>) are based upon pseudo-random number generators, a quite complex field. You can still get a PhD by inventing better PRNGs.
If you want to understand how rand is (or can be) implemented, you'll better study the source code of some existing free software C standard library (like e.g. GNU glibc or musl-libc).
If you want to understand how <random> is implemented, study the source code of your C++ standard library. If you use the GCC compiler (e.g. compiling with the g++ program), it is provided by it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm writing a genetic algorithm to solve the Master Mind game. I've done lots of research on best approaches and it's incredibly important to have a diverse population. I'm trying to determine how to get really good random numbers in C++. I've done srand(time(NULL)) at the start of my program to set the seed then I've simply used rand(). What I would like to know is how random is that really? Is it pretty good? Are there other better libraries for random numbers?
I know number theory and randomness is a very complicated subject; do you have any pointers in writing your own version of rand()?
For crypto, you need very strong properties on your random numbers. Much of the literature out there focusses on these sorts of requirements. A typical solution would be seeding iterated applications of SHA-256 using environmental noise (hard drive delays, network packets, mouse movements, RDRAND, HAVEGE, ...).
For Monte-Carlo simulations or AI applications, the randomness requirements are much lower indeed. In fact, very simple generators will be good enough. The most basic is the infamous Linear Congruential generator, which is considered a bit old-fashioned now, because the output patterns sometimes produce noticeable and unwanted sampling effects (in particular, some experimental studies done in the 70s and 80s are quite probably flawed because of this). These days, the Mersenne Twister is more popular, and is more than adequate for a computer game. It's available in the C++ standard library: see std::mt19937.
rand()'s randomness is really bad. It is a bog standard LCG and generally has bad randomness and bad quality of projection. If you are serious about quality of randomness for your application, you need to go with something better. Then it depends on whether you want to keep to the standard library, or not.
If you want to use standard library, go with <random> header and Mersenne Twister.
But, I would recommend to you to use the PCG random family instead. Its fast, it has good quality and fixes most of mistakes of <random>.
Background: I use rand(), std::rand(), std::random_shuffle() and other functions in my code for scientific calculations. To be able to reproduce my results, I always explicitly specify the random seed, and set it via srand(). That worked fine until recently, when I figured out that libxml2 would also call srand() lazily on its first usage - which was after my early srand() call.
I filled in a bug report to libxml2 about its srand() call, but I got the answer:
Initialize libxml2 first then.
That's a perfectly legal call to be made from a library. You should
not expect that nobody else calls srand(), and the man page nowhere
states that using srand() multiple time should be avoided
This is actually my question now. If the general policy is that every lib can/should/will call srand(), and I can/might also call it here and there, I don't really see how that can be useful at all. Or how is rand() useful then?
That is why I thought, the general (unwritten) policy is that no lib should ever call srand() and the application should call it only once in the beginning. (Not taking multi-threading into account. I guess in that case, you anyway should use something different.)
I also tried to research a bit which other libraries actually call srand(), but I didn't find any. Are there any?
My current workaround is this ugly code:
{
// On the first call to xmlDictCreate,
// libxml2 will initialize some internal randomize system,
// which calls srand(time(NULL)).
// So, do that first call here now, so that we can use our
// own random seed.
xmlDictPtr p = xmlDictCreate();
xmlDictFree(p);
}
srand(my_own_seed);
Probably the only clean solution would be to not use that at all and only to use my own random generator (maybe via C++11 <random>). But that is not really the question. The question is, who should call srand(), and if everyone does it, how is rand() useful then?
Use the new <random> header instead. It allows for multiple engine instances, using different algorithms and more importantly for you, independent seeds.
[edit]
To answer the "useful" part, rand generates random numbers. That's what it's good for. If you need fine-grained control, including reproducibility, you should not only have a known seed but a known algorithm. srand at best gives you a fixed seed, so that's not a complete solution anyway.
Well, the obvious thing has been stated a few times by others, use the new C++11 generators. I'm restating it for a different reason, though.
You use the output for scientific calculations, and rand usually implements a rather poor generator (in the mean time, many mainstream implementations use MT19937 which apart from bad state recovery isn't so bad, but you have no guarantee for a particular algorithm, and at least one mainstream compiler still uses a really poor LCG).
Don't do scientific calculations with a poor generator. It doesn't really matter if you have things like hyperplanes in your random numbers if you do some silly game shooting little birds on your mobile phone, but it matters big time for scientific simulations. Don't ever use a bad generator. Don't.
Important note: std::random_shuffle (the version with two parameters) may actually call rand, which is a pitfall to be aware of if you're using that one, even if you otherwise use the new C++11 generators found in <random>.
About the actual issue, calling srand twice (or even more often) is no problem. You can in principle call it as often as you want, all it does is change the seed, and consequentially the pseudorandom sequence that follows. I'm wondering why an XML library would want to call it at all, but they're right in their response, it is not illegitimate for them to do it. But it also doesn't matter.
The only important thing to make sure is that either you don't care about getting any particular pseudorandom sequence (that is, any sequence will do, you're not interested in reproducing an exact sequence), or you are the last one to call srand, which will override any prior calls.
That said, implementing your own generator with good statistical properties and a sufficiently long period in 3-5 lines of code isn't all that hard either, with a little care. The main advantage (apart from speed) is that you control exactly where your state is and who modifies it.
It is unlikely that you will ever need periods much longer than 2128 because of the sheer forbidding time to actually consume that many numbers. A 3GHz computer consuming one number every cycle will run for 1021 years on a 2128 period, so there's not much of an issue for humans with average lifespans. Even assuming that the supercomputer you run your simulation on is a trillion times faster, your grand-grand-grand children won't live to see the end of the period.
Insofar, periods like 219937 which current "state of the art" generators deliver are really ridiculous, that's trying to improve the generator at the wrong end if you ask me (it's better to make sure they're statistically firm and that they recover quickly from a worst-case state, etc.). But of course, opinions may differ here.
This site lists a couple of fast generators with implementations. They're xorshift generators combined with an addition or multiplication step and a small (from 2 to 64 machine words) lag, which results in both fast and high quality generators (there's a test suite as well, and the site's author wrote a couple of papers on the subject, too). I'm using a modification of one of these (the 2-word 128-bit version ported to 64-bits, with shift triples modified accordingly) myself.
This problem is being tackled in C++11's random number generation, i.e. you can create an instance of a class:
std::default_random_engine e1
which allows you to fully control only random numbers generated from object e1 (as opposed to whatever would be used in libxml). The general rule of thumb would then be to use new construct, as you can generate your random numbers independently.
Very good documentation
To address your concerns - I also think that it would be a bad practice to call srand() in a library like libxml. However, it's more that srand() and rand() are not designed to be used in the context you are trying to use them - they are enough when you just need some random numbers, as libxml does. However, when you need reproducibility and be sure that you are independent on others, the new <random> header is the way to go for you. So, to sum up, I don't think it's a good practice on library's side, but it's hard to blame them for doing that. Also, I could not imagine them changing that, as billion other pieces of software probably depend on it.
The real answer here is that if you want to be sure that YOUR random number sequence isn't being altered by someone else's code, you need a random number context that is private to YOUR work. Note that calling srand is only one small part of this. For example, if you call some function in some other library that calls rand, it will also disrupt the sequence of YOUR random numbers.
In other words, if you want predictable behaviour from your code, based on random number generation, it needs to be completely separate from any other code that uses random numbers.
Others have suggested using the C++ 11 random number generation, which is one solution.
On Linux and other compatible libraries, you could also use rand_r, which takes a pointer to an unsigned int to a seed that is used for that sequence. So if you initialize that a seed variable, then use that with all calls to rand_r, it will be producing a unique sequence for YOUR code. This is of course still the same old rand generator, just a separate seed. The main reason I meantion this is that you could fairly easily do something like this:
int myrand()
{
static unsigned int myseed = ... some initialization of your choice ...;
return rand_r(&myseed);
}
and simply call myrand instead of std::rand (and should be doable to work into the std::random_shuffle that takes a random generator parameter)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm currently expanding a simulation model that relies heavily upon random normal distributed numbers. Currently it uses std::normal_distribution, but it's too slow.
Is there a way to implement a fast random normal distribution? The values don't have to be unique as long as it follows a normal distribution.
The Ziggurat generator by Marsaglia and Tsang (JSS, 2000) has been seen to be both statistically sound and fast. You do however want the revised Ziggurat normal generator which uses a better underlying uniform generator as per the comment of Leong et al (JSS, 2005).
I have the original papers as well as a few review papers in this GitHub directory which is part of a Ziggurat C++ implementation for R.
std::normal_distribution is a distribution, not a generator. You may want to try out other generator from the standard library and see what's fastest (see http://en.cppreference.com/w/cpp/numeric/random).
If the quality of the numbers is not that important, you could fall back to very simple algorithms, as simple as taking r=++i%6, for example.
A Linear congruential generator is easy to implement, too (actually, most standard rand() implementation use some implementation thereof. However, it will probably not be faster than using std::linear_congruential_engine. At the above linked site there's also a number of readily "configured" random number generators.
There's also an algorithm by the late Marsaglia, which can be found here and which is quite efficient w.r.t. performance and number quality.
At the end, make sure to use proper optimization flags when testing for performance.
The standard <random> library allows to produce random numbers using combinations of generators and distributions. You are using the normal distribution, and what you want is a faster generator then the default, have a look here.