Being able to issue random strings or integers in programming has long been a topic of fascination. Although this article doesn't attempt to tackle the profound questions on randomisation because, well, I'm not at all good at maths, it does teach you how you can make the possibilities of getting the same random number so slim it's almost impossible.
The truth is that nothing is truly random, everything is based on something. For instance, I could throw out the word "Mash Potato" to you right now. Is it totally random? Or is it because I had it for my tea 5 nights ago? I could even pick out the 5 of diamonds from a stack of cards, seemingly totally random, but my option was based on something in my mind telling me to choose the card from that position.
The same goes for a computer. A computer can never be truly random. It can only throw out a random value based on the information it is fed. I could write the longest set of functions in the world in my PHP script, but it'd still boil down to certain factors. I've given it an IP address and it's given me 3 random numbers based on that IP address back to me, it's not random, it's just based on what the function does to return those 3 numbers to me.
All the philosophical stuff aside, however, we can return a fairly random string. Take the following example and ascertain whether or not it'd be viable in a small to medium sized application.
$iN = rand(0, 9);
$iN is always going to be anywhere from 0 to 9. On the 11th execution of the script it is inevitable that you will have had that number already. I'd be very surprised if it would take to the 11th go to repeat a number. The odds are stacked well against it as your chance decreases by 1 upon every single execution.
Although rand(); may be a fairly quick way to generate a random number, it is not the best way on its own. For example rand(1000, 2000); would be a better solution but again your chances are still very limited. After all, the numbers we count in are base 10. That is: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Whereas a numbering system such as hex (hexadecimal) is a base 16 numbering system: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. That way a function that returned a random value would give you more possibilities in hexadecimal then in decimal. To sum it up, a base 2 system such as binary would be absolutely useless.
So what's the solution? In the interest of usability, you must find a nice spot between giving yourself a lot of possibilities with a very slim chance of repetition, and speed. Take the following as an example:
This will give you a 5 character return value based on the base 16 numbering system. The line will shuffle the user's IP address with a random number from 1000 to 9999. It is a quick randomisation technique that which will give you a lot of possibilities.
However, there is another function worth mentioning in PHP that could help us in our randomisation dilemma, mktime() is the amount of seconds between the Unix epoch (January 1st, 1970 - 00:00:00 GMT) and the current date specified via the 2nd argument.
Note: The second option for mktime() is optional. If unspecified then mktime() will return the amount of seconds between Unix epoch and the current time and date.
This mktime() function will be unique every second. The amount of seconds will never repeat themselves but merely continue on and on into the future. This will give us an unbelievably slim possibility that we will have repeating numbers. For it to occur we would have to have generated the exact random number at the exact same second in time. I'm sure you can deduce that just about everything is on our side. Thus:
$szRand = md5(mktime() . rand(0, 25));
Although we're back to a narrow 0 to 25 random integer, we have increased our chances of not repeating a number by thousands. For us to get the same random number now, the function would have to output the same number from the rand(0, 25); at the exact same second. You may use substr() to cut down the value somewhat, but just bear in mind that cutting mktime() down will increase the chance of the value being repeated again.
The way the folks at YouTube do it with their random values for video links, is by storing the unique ID in the database and then checking to see if it is unique. If it isn't, generate a new 1 until it's unique. Remember though, nothing is truly unique, without having anything to check the random value against we can only make the possibility of repetition so narrow and unlikely it's highly impossible.
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Good article. A small mention of srand and mt_srand (mt_round being the preferred method) may have been beneficial as they allow you to seed the random number generator; the latter using the Mersenne Twister algorithm.