0

I am trying to come up with a solution to generate a Unique Id preferably on the Fly. Usage scope could be Order, Product or Plan Id, where there is no security involved.

I don't like idea of generating a random number and then querying the db to check its uniqueness and repeating the process if it is not in this case where security isn't an issue.

Also I don't prefer using Auto Increment id since it looks so simple.

My initial thought is to use a combination of Auto Increment id + timestamp converting the decimal value to hex so it looks like a random string. And then finally prefixing and suffixing it with 2 digit random string.

function generateUID($num){
    $str = dechex(time()+ intval($num));
    $prefix = dechex(rand(1,15));
    $suffix = dechex(rand(1,15));

    return strtoupper($suffix.$str.$prefix);

}

Where $num is the auto_increment id Returns something like E53D42A046

Is this the right way to go about doing this, are there collision issues ?

I thank all responses..!

I acknowledge the usefulness of uniqid() but in this context to be genuinely unique Auto_Increment need to play a significant part so how will it do so in uniqid. Passing it as a prefix would result in a Product id which vary greatly in size. (153d432da861fe, 999999953d432f439bc0).

To expand the scope further, Ideally we want a unique code which looks random with fairly consistent length and could be reversed to the auto_increment id from which it was created.

Samosa
  • 845
  • 7
  • 19
  • You can use a mix of UNIX timestamp along with a random function. You'll be guaranteed uniqueness with no collisions. *"Also I don't prefer using Auto Increment id since it looks so simple."* - Sometimes, even the things that appear to be the most simple, can be just as effective. – Funk Forty Niner Jul 26 '14 at 22:35
  • Ok gr8.. I guess then what I did, adding UNIX timestamp with auto increment id should be unique 100%? – Samosa Jul 26 '14 at 22:38
  • Yes, along with an auto increment, that would be extremely hard to get a collision, and I mean "extremely". – Funk Forty Niner Jul 26 '14 at 22:39
  • As per the manual on [`uniqid()`](http://php.net/manual/en/function.uniqid.php) - *Can be useful, for instance, if you generate identifiers simultaneously on several hosts that might happen to generate the identifier at the same microsecond.* - ***Warning** This function does not create random nor unpredictable strings. This function must not be used for security purposes. Use a cryptographically secure random function/generator and cryptographically secure hash functions to create unpredictable secure IDs.* – Funk Forty Niner Jul 26 '14 at 22:46

1 Answers1

2

Such a function already exists - uniqid()

http://php.net/manual/en/function.uniqid.php

It works based on the timestamp down to the microsecond - you can add a prefix based on the process ID to further refine it. There are a couple more robust versions out there as well - see PHP function to generate v4 UUID

Community
  • 1
  • 1
Sam Dufel
  • 17,560
  • 3
  • 48
  • 51
  • But can I rely on that in the context of assigning id without querying the table for uniqueness. – Samosa Jul 26 '14 at 22:32
  • @Samosa Just put a UNIQUE constraint on the column, and if there's an error, generate another id. – Dave Chen Jul 26 '14 at 22:32
  • @Samosa - unless you're generating multiple IDs in the same microsecond, yes, it's guaranteed to be unique. If you are, you might want to use `http://php.net/manual/en/function.getmypid.php` as the prefix value – Sam Dufel Jul 26 '14 at 22:35
  • If you're generating multiple IDs in the same script, then the pid will also be the same. – Dave Chen Jul 26 '14 at 22:50
  • @DaveChen - yes, but php is a largely a single-threaded language - you can generate IDs in the same script in sequence, but not in parallel. Internally, uniqid() includes a very short delay, which prevents successive calls from using the same timestamp. – Sam Dufel Jul 27 '14 at 15:35
  • @SamDufel I'm only pointing out that there's always a chance of a collision within the database. The surr method is to add a unique column so that you don't query and check if the column already exists (racing condition). – Dave Chen Jul 27 '14 at 16:14