0

I have searched high and low for an answer with no avail.

I am trying to insert a random id number for my users between 9999,99999999. Problem is they have to be unique. I have everything set up but with an auto increment set for the id. I figured I will keep the auto increment field and just add another row for the unique id.

This is what I got so far:

$id = mt_rand(9999,99999999);

    $query = "SELECT * FROM accounts";

    $result = mysql_query($query) or die(mysql_error());

    while($account = mysql_fetch_array($result)){

        if ($id == $account['id']){

    $id = mt_rand(9999,99999999);

    } else {

    $sql = "INSERT INTO accounts (id, username, email, password, sex)
    VALUES ('$id', '$username', '$email', '$password', '$sex')";
    mysql_query($sql);}}

Now I figured if I create a random number, check the database if it exists create another, else insert it, but it is not working, if it a simple solution I apologise.

Thanks again :)

4
  • isnt the auto_increment already unique? Commented Mar 31, 2011 at 18:04
  • (If 'auto_increment' is used, it can be set to an initial value, if it's just the lower-limit that's of a concern. It won't help if the requirements is a "random ID", but I would suggest keeping the internal ID different from an exposed ID which mostly removes the need [? for obsecurity ?] of a random PK.) Commented Mar 31, 2011 at 18:11
  • I am going to have 2 id fields, one called base id, which the member will never know, and there unique id which is what they will use, in my php the base id will be used to update accounts and whatnot as a security measure as accounts will be transferring money. Commented Mar 31, 2011 at 18:22
  • 2
    If the purpose is to obfuscate the true primary key in query strings, cookies and sessions, then hashing the ID (ideally with a per-user salt) woud be a better approach. Users themselves should never really need to "use" their integer ID. Commented Mar 31, 2011 at 18:28

4 Answers 4

3

this may seem like a silly answer:

If you are already using auto_increment on a unique key, there is not a need to add another unique key

Sign up to request clarification or add additional context in comments.

Comments

1

The code that follow is almost 100% sure that your will never repeat, I use myself, never hava any problem.

 function guid(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);  // "-"
        $uuid = chr(123)    // "{"
                .substr($charid, 0, 8).$hyphen
                .substr($charid, 8, 4).$hyphen
                .substr($charid,12, 4).$hyphen
                .substr($charid,16, 4).$hyphen
                .substr($charid,20,12)
                .chr(125);  // "}"
        return $uuid;
    }
 }

If you think it is not enough, try to create an prefix before the number, it can be the Year date('Y');

Good Luck

6 Comments

While a random GUID is [for most practical purposes] guaranteed to "be globally unique", the upper limit here is 99999999 (which is much much smaller than the ~2^127 of a random GUID) and any trivial mapping to this smaller codomain will lead to the Birthday Problem.
@Fernando Costa It's still the Birthday Problem :-) The Mersenne PRNG has a very good cycle length but the result codomain is much smaller than the internal domain.
@pst If you really insist ;) - mersenne twister script --> php.net/manual/en/function.mt-rand.php#99319 after generates the number, before insert, check in your database if the number already exists.
@Fernando Costa I can buy that :-)
@Fernando Costa "buy that" = "accept" -- the additional check to the DB is required to ensure a true unique value.
|
1

While not a "strong" PRNG (this is actually very weak), one approach is to use a PRNG as described in one-to-one random mapping. This particular solution is shows a PRNG solution for which the cycle length is the range. However, this solution can't be used 'as is' because the domain is different.

See Random-Order Keys -- indirectly from link above -- and the following sections which uses an Additive Congruential Method / Linear Feedback Shift Register PRNG. Here is a table showing the tap positions -- using a 2^23 would allow picking a guaranteed unique number between [9999, 9999 + 2^23-1) or [9999, 8398606). However, other transactional factors, such as "picking an ID but not using it" should be consider.

Obviously this should not be used for true "security" (even with a "true random random", a nonce -- which needs no unique constraint! -- and/or other verification system should be employed and the random IDs are simply an "obscurity" -- these are not security! -- layer.)

Happy coding.

Comments

0

you could just generate a uid, then check to see if it is used.

<?php
  do {
    $uid = rand(9999,99999999);
    $sql = "SELECT * FROM `table` WHERE `uid`=$uid";
    $result = mysql_query($sql);
  while (mysql_num_rows($result) > 0);
    // have $uid

?>

Or because you have the uid, then you could just run an equation on that to generate a uid (like a md5 or sha256 hash or something).

4 Comments

Please don't use 'goto' here. I'm not even going to say anything about the SQL string-generation (except this) this time ^^
Alright, I'll bite @pst, what is wrong with the sql generation?
@pst So is this approach unsound? your comment generates heat but not much light.
@MaxHodges See the first revision for the use of goto. And see stackoverflow.com/questions/60174/… or bobby-tables.com for the latter. The fact that it is known to always be a number is irrelevant. Use the proven approach. Teach good habits. Be consistent. Avoid [buggy code] surprises.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.