TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 09-19-2007, 09:38 AM   #1 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,215
Thanks: 90
Wildhoney is on a distinguished road
How Rdoanm is Rondam?

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.

PHP Code:
$iN rand(09); 
$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:

PHP Code:
$szRand substr(str_shuffle(md5($_SERVER['REMOTE_ADDR'] . rand(10009999))), 05); 
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:

PHP Code:
$szRand md5(mktime() . rand(025)); 
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.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 09-19-2007, 11:34 AM   #2 (permalink)
The Reckoner
Advanced Programmer Top Contributor 
 
Karl's Avatar
 
Join Date: Sep 2007
Posts: 437
Thanks: 22
Karl is on a distinguished road
Default

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.
Karl is offline  
Reply With Quote
Old 09-19-2007, 01:14 PM   #3 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,239
Thanks: 3
Salathe is on a distinguished road
Default

Regarding seeding the random number generator:
Quote:
Note: As of PHP 4.2.0, there is no need to seed the random number generator with srand() or mt_srand() as this is now done automatically.
__________________
salathe@php.net
Salathe is offline  
Reply With Quote
Old 09-19-2007, 01:32 PM   #4 (permalink)
The Reckoner
Advanced Programmer Top Contributor 
 
Karl's Avatar
 
Join Date: Sep 2007
Posts: 437
Thanks: 22
Karl is on a distinguished road
Default

Well in that case, my only observation would be to suggest mt_rand as an aternative to rand - for one, it's apparently upto four times quicker than rand

http://uk.php.net/mt_rand
Karl is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 12:00 PM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design