yohairosen
yohairosen

Reputation: 1685

Generating unique reference ids using Hashids

In my DB, I need to have unique reference ids to orders, to show the end users.

My schema includes many accounts that can potentially have many customers, which can make many orders (occasionally at the same time - both different customers, and a single customer with many orders)

I've decided to use Hashids in order to solve this. I came up with this:

//create a unique salt using the account id + current timestamp:
var hashids = new Hashids(accountId + '-' + new Date().getTime(), 8,
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ')

//Then, generate a unique id for every order using:
for(var i = 0; i < orders.length; i++ ) {
   orders[i].ref_number = hashids.encode(i, a.date.getTime())
}

How random would this be? How can I validate that?

Thanks

Upvotes: 0

Views: 3045

Answers (2)

Loque
Loque

Reputation: 241

It's simpler than you think. From the documentation of Hashids:

1) The salt should not be random in order to avoid collisions

There are no collisions because the method is based on integer to hex conversion. As long as you don't change constructor arguments midway, the generated output will stay unique to your salt.

2) Check how random the IDs look

Additionally, we encourage you to pre-generate a large number of ids for testing purposes — to analyze their uniqueness, whether they look random enough for your project and what your upper integer limit is (which usually depends on your system/language).

Here you have an example of how to pre-generate a large number of ids:

const salt = 'my salt'
const idsLength = 10
const hashids = new Hashids(salt, idsLength)

let idsCollector = []

for (let i = 0; i < 1000; i++) {
  idsCollector.push(hashids.encode(i))
}

console.log(idsCollector)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/hashids.min.js"></script>

REMEMBER! When defining the salt variable, it has to remain the same for all users and sessions, if not every user will have a different hash id making link sharing impossible. The same goes for the length!

Upvotes: 1

Bill Karwin
Bill Karwin

Reputation: 562270

same-length, unique id string that I can show to end users so they can reference their orders

How about a concatenation of the customer id and the auto-increment order id?

Suppose your table is:

CREATE TABLE `orders` (
  `order_id` int(11) NOT NULL AUTO_INCREMENT,
  `cust_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`order_id`)
);

With this data:

insert into orders values (8675309, 123);

You can create a VIEW to produce the customer reference to the order:

CREATE OR REPLACE VIEW cust_orders_ref AS
SELECT CONCAT(LPAD(cust_id, 4, '0'), '-', LPAD(order_id, 11, '0')) AS order_ref
FROM orders;

Output:

select * from cust_ref;
+------------------+
| order_ref        |
+------------------+
| 0123-00008675309 |
+------------------+

Upvotes: 1

Related Questions