Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

EDIT AGAIN : I don't want to create another question, so asking here. I have the same situation. But this time I need the algo in C language. Can any body help me.

I have following table.

CREATE TABLE IF NOT EXISTS `j741_order` (
  `order_id` int(11) NOT NULL AUTO_INCREMENT,
  `buyer_id` int(11) NOT NULL,
  `subtotal` decimal(15,5) DEFAULT '0.00000',
  `discount` decimal(15,5) NOT NULL DEFAULT '0.00000',
  `shipping` decimal(15,5) DEFAULT '0.00000',
  `tax` decimal(15,5) DEFAULT '0.00000',
  `total` decimal(15,5) NOT NULL DEFAULT '0.00000',
  `currency` char(3) DEFAULT NULL,
  `status` int(11) NOT NULL DEFAULT '0',
  `created_date` datetime NOT NULL,
  `modified_date` datetime NOT NULL,
  PRIMARY KEY (`order_id`),
  KEY `idx_buyer_id` (`buyer_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

I want to generate a unique Order Id, (just to show to user) so that user can not guess what will be the next Order Id.

How can I get that Unique Random Order Id from original Order If

and get back original order Id from that Random Order Id?

EDIT : I don't want to create any other field.

like image 681
Gaurav Avatar asked Mar 22 '11 06:03

Gaurav


People also ask

Is order number unique?

The order number is not guaranteed to be unique. Two orders will have the same order number if they both happened at the same millisecond and also both have the same padding digit. It's important to understand the probability for a collision to see if this can work reasonable in a real system.

How to generate order id in PHP?

If you want to generate a unique ID in your DB, then leave it to your DB, using auto-increment. Anyway, you could use a combination of microtime() and rand().


1 Answers

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

like image 145
Shane O'Grady Avatar answered Sep 19 '22 15:09

Shane O'Grady