Generating a Truly Unique Order Id in PHP

Generating a truly unique order id in PHP?

Assuming your users are authenticated and have a user id:

$unique_id = time() . mt_rand() . $userid;

If the same user requests this page a second time in the same second, there will still be a chance of 1 in mt_getrandmax(), which on my machine returns 2147483647. You can probably live with that?

If your users are not authenticated, you can use a hash of their IP address instead if you'd like.

How to generate Unique Order Id (just to show touser) with actual Order Id?

If your requirements are:

  • It must be reversible (i.e. given just the "random" ID, you can find the original order_id)
  • No extra columns
  • You don't want to show the original/internal order_id to the user at all

then I would recommend some kind of two-way encryption. Hashing won't work as you can't find the original value from a hash.

I'm also adding that it should be human-friendly e.g. someone can call it out over the phone to you

I'm going to use a very simple two way encryption class located here, which was written by Tony Marston.

We want the solution to be human-friendly so let's remove some of the scramble chars. I've left only uppercase characters, numbers and the space and dash symbols. All of these can be easily communicated using the standard phonetic alphabet, and the forced use of uppercase removes any confusion as to what a character is.

These are the scramble strings I used (I used this online word scrambler rather than trying to scramble the string myself):

    $this->scramble1 = '0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ ';
$this->scramble2 = 'UKAH652LMOQ FBDIEG03JT17N4C89XPV-WRSYZ';

So the code to create our human-friendly order id is:

<?php

include 'encryption_class.php';

$crypt = new encryption_class();

$key = "A-COMPLETELY-RANDOM-KEY-THAT-I-HAVE-USED";
// Min length of 8 for encrypted string
$min_length = 8;

$order_id = 123456789;

print "Original: " . $order_id . PHP_EOL;

$encrypt_result = $crypt->encrypt($key, $order_id, $min_length);

print "Encrypted: " . $encrypt_result . PHP_EOL;

// DECRYPT
$decrypt_result = $crypt->decrypt($key, $encrypt_result);

print "Decrypted: " . $decrypt_result . PHP_EOL;

?>

(You need to download and save the *encryption_class* file locally, and include it).

I ran that code from the command line and received the following output:

Original: 123456789
Encrypted: 2UD5UIK9S
Decrypted: 123456789

Now we have our short, human-friendly order_id, which can be used in a URL such as http://myapp.example.com/order/view/2UD5UIK9S, and you never need to display or communicate the internal order_id to your users.

Notes:

The encrypted code will be unique once your order_id is unique (since it's a PK it will be)

This should not be used as a password encryption/decryption routine - don't store passwords, store hashes.

Make sure your secret key is random, complex and contains only the characters in your $scramble variables.

It obfuscates the order_id only.

Edit:

Although padding the input string (order_id) generates a certain amount of ramdomness, you could combine this with @biakaveron's answer to create a URL like http://myapp.example.com/order/view/5cc46aea44e898c3b4e1303eb18d8161302cd367/2UD5UIK9S

How to produce a short unique id in php?

Uniqid is not guaranteed to be unique, even in its full length.

Furthermore, uniqid is intended to be unique only locally. This means that if you create users simultaneously on two or more servers, you may end up with one ID for two different users, even if you use full-length uniqid.

My recommendations:

  • If you are really looking for globally unique identifiers (i.e. your application is running on multiple servers with separate databases), you should use UUIDs. These are even longer than the ones returned by uniqid, but there is no practical chance of collisions.

  • If you need only locally unique identifiers, stick with AUTO_INCREMENT in your database. This is (a little) faster and (a little) safer than checking if a short random ID already exists in your database.

EDIT: As it turns out in the comments below, you are looking not only for an ID for the user, but rather you are forced to provide your users with a random login name... Which is weird, but okay. In such case, you may try to use rand in a loop, until you get one that does not exist in your database.

Pseudocode:

$min = 1;
do {
$username = "user" . rand($min, $min * 10);
$min = $min * 10;
} while (user_exists($username));
// Create your user here.

Generate Unique Order ID

Sorry for the late reply, was at school and I didn't wanna get caught, but if you're still having the problem, you can use PDO in this way:

$statement = "SELECT * FROM table WHERE column = 'what_id_to_search_for'";
$query = $pdo->query($statement, PDO::FETCH_ASSOC); # FETCH_ASSOC just returns an assosiative array.
if ($query->rowCount())
{
# The row exists! Do again! (re-call function, etc...)
} else {
# The row doesn't exist! Woo! We can insert!
}

If you're using MySQLi, etc... please let me know I'll delete my answer cause I don't like that connection language, and if that doesn't make sense I can rewrite it to make it simpler for you,

Also, I don't see why you don't just use an AUTO_INCREMENT type and then just set a type like TLP for example. :-)

Best of luck!

Generate unique ids

Have you looked into uniqid()?

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

Generating a unique ID in PHP

string uniqid ([ string $prefix [, bool $more_entropy ]] )

Gets a prefixed unique identifier based on the current time in microseconds.

USAGE: $id = uniqid(rand(), true);


Related Topics



Leave a reply



Submit