...

View Full Version : Quickest way to choose a random number NOT already chosen



mutasim
06-03-2007, 09:02 PM
I have seen snippets of how to create a random number using php.

But what would be the most efficient and quick-running method of creating a random number that was not already created (stored in a MYSQL database).

Just a method please.... I think I can code it ;)

- Mutasim

rafiki
06-03-2007, 09:05 PM
a random number
hmm this is a hard one....
rand(); (http://uk2.php.net/rand)

mr e
06-03-2007, 09:09 PM
So you're storing the already generated numbers in a database?

What's the range of numbers you want?

mutasim
06-03-2007, 09:10 PM
So you're storing the already generated numbers in a database?

What's the range of numbers you want?

well 5 digit numbers really so 00001- 99999

rafiki
06-03-2007, 09:16 PM
sorry it wasnt sarcasm it was a joke, but that is how you generate a random number that is not stored in a mysql database!

rafiki
06-03-2007, 09:36 PM
well 5 digit numbers really so 00001- 99999
could use
$arr = range(00001,99999);
$i = shuffle($arr);
echo "Random Number is $i";

mr e
06-03-2007, 09:45 PM
Do you need to just generate unique random numbers for the duration of the script? Or do you need them to be permanently random?

If you let us know what you're using them for we might be better able to help you

printf
06-03-2007, 09:54 PM
Just create a list of numbers in the valid range, then use shuffle, then insert them into file and use fseek to extract the next number in the file, keeping track of the next number to extract in the same file. Random, resource friendly and never will there be a chance that you will return the same number! File list can also auto resets when you get to the end of the file. Great for CAPTCHA security image system.

NancyJ
06-03-2007, 10:54 PM
Unless I'm missing something I'm still not seeing whats wrong with rand().


$randomNumber = str_pad(rand(1,99999), 5, "0", STR_PAD_LEFT);

Use rand to pick a random number between 1 and 99999 and then pad it out with zeros

mutasim
06-03-2007, 10:57 PM
It will act as a primary key... so needs to be unique + random

twomt
06-03-2007, 11:11 PM
$a = rand(00001,99999);
$rows = mysql_query( SELECT count(*) from table where key = $a );
while ( $rows != 0 ) {
$a = rand(00001,99999);
$rows = mysql_query( SELECT count(*) from table where key = $a );
}

something like that, just generate a number and see if it exists. If yes, generate a new number. I must say though that sooner or later this will lead to trouble as well I guess.

mr e
06-03-2007, 11:13 PM
I'm just going out on a limb here, but if you're wanting to select random rows from a table, you can do "ORDER BY RAND() LIMIT 5" for example

Otherwise perhaps having one field with all the numbers you've used separated by commas, then you could query that one field, explode the numbers, and while your randomly generated number is in the exploded array, generate a new random number, when you fail to meet the condition you'll have a unique random number

Or just query for every id (or whatever your field is called) and loop through and add all those id's to an array, then continue with the above method

mr e
06-03-2007, 11:15 PM
$a = rand(00001,99999);
$rows = mysql_query( SELECT count(*) from table where key = $a );
while ( $rows != 0 ) {
$a = rand(00001,99999);
$rows = mysql_query( SELECT count(*) from table where key = $a );
}

something like that, just generate a number and see if it exists. If yes, generate a new number. I must say though that sooner or later this will lead to trouble as well I guess.

You realize in a worst case scenario you just made 10,000 queries right ;)

twomt
06-03-2007, 11:16 PM
As I said, sooner or later this will lead to trouble :p

ralph l mayo
06-03-2007, 11:24 PM
Fill a table key_pool(id int) with all 99999 possibilities, and when you insert a new row to your other table grab an id from key_pool (order by rand() limit 1) and delete from the key_pool. You can do this all transparently from a trigger on insert. This method substitutes sudden catastrophe for the slow degradation of the collision method supra.

CFMaBiSmAd
06-04-2007, 12:10 AM
It will act as a primary key... so needs to be unique + randomA primary key only needs to be unique, not random. Just use an auto increment field, that is what they are for.

rafiki
06-04-2007, 01:16 AM
isnt there a way to set a field unique? and it gives it a unique token

PappaJohn
06-04-2007, 02:01 AM
Setting a column as the primary index forces the values to be unique.

You can use the php function uniqid() to generate a unique token.

aedrin
06-04-2007, 04:48 PM
What's wrong with MySQL's auto generated numbers? Do you really -need- them random?

Sometimes a problem can be removed altogether by changing the requirements.

If you don't care about resources, you could get all current IDs from the database and put them in an array, then intersect it with a complete list of all possible IDs and choose a random one from that.


Setting a column as the primary index forces the values to be unique.

You can use the php function uniqid() to generate a unique token.

Except your query will fail when you try to insert an existing value. And uniqid() doesn't work as the requirements preclude any non numeric values. Not to mention that uniqid() is not guaranteed to be unique.

It's surprising how easy it is to respond to a topic without reading the question.

ralph l mayo
06-05-2007, 02:23 AM
And uniqid() doesn't work as the requirements preclude any non numeric values. Not to mention that uniqid() is not guaranteed to be unique.

uniqid does return a (hex) numeric value you can store in a bigint field by giving its output the hex prefix, e.g. INSERT INTO foo(id) VALUES(0x4664b8d45d763)

Also, it is guaranteed to be unique except in cases of defective hardware clocks and in concurrent applications, and in the latter case you can assure uniqueness using the prefix parameter. It's not an entirely bad solution for storing unique ids for small applications in MySQL < 5.0 (after 5.0 there's a UUID() function that's much better)

As for why you'd want to store that instead of an auto-increment anyway, see http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

aedrin
06-05-2007, 04:42 PM
What's the range of numbers you want?
well 5 digit numbers really so 00001- 99999


As for why you'd want to store that instead of an auto-increment anyway

I think if someone knows about these two methods, they wouldn't be asking this question. So it would be easy and safe to use an auto increment field. Not to mention that most tutorials and books use it. And most business environments.

mutasim
06-05-2007, 07:24 PM
the random-ness was meant to stop people being able to edit URL's and use someone elses id.

Suppose, using URL strings is unsafe as it is...

Thanks for the help anyways ;)

CFMaBiSmAd
06-05-2007, 10:43 PM
the random-ness was meant to stop people being able to edit URL's and use someone elses id.Only relying on a value in a parameter in the URL is not the way to do this. Someone could just write a script that goes through and submits each possible value.

You need to use a real user registration/login system and then if you are passing something like a record number as part of the URL, test that the currently logged in user is the owner of that information immediately prior to making any changes to it.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum