Typically you use srand() when you need to start the random number generator in a random place. You may do this because you are going to generate some keys or coupons and want them to start in an unpredictable place.
From time to time we provide special offers to customers in the form of a unique coupon code that can be used at purchase to get a specific discount. These coupons are also used to provide discounts to customers upgrading from say Performance Validator to C++ Developer Suite so that they do not pay for Performance Validator twice.
When the coupon management system was written, we used srand(clock()) thinking that would be an acceptable random value for generating coupons. The thinking was the management system would be running all the time and thus clock() would return a value that was unlikely to be hit twice for the number of valid coupons at any one time. However, the way the system is used is that users close the coupon management system when not in use and thus clock() will return values close to the starting time (start the app, navigate to the appropriate place, generate a coupon).
Result: Sooner or later a duplicate coupon is created. And that is when we noticed this problem.
This resulted in a confused customer (“My coupon has already been used”), a confused member of customer support (“That shouldn’t be possible!”) followed by some checking of the coupon files and then the code to see how it happened. Easy to fix, but better selection of the seed in the first place would have prevented the problem.
So if you want better random numbers don’t use clock() to seed srand().
- Use time(NULL) to get the time of day and cast the result to seed srand().
time(NULL) returns the number of seconds elapsed since midnight January 1st, 1970.
- Use rdtsc() to get the CPU timestamp and cast the result to seed srand().
rdtsc() is unlikely to return duplicate values as it returns the number of instructions executed by the processor since startup.