Question

I'm using mysql database auto-increment as an order ID. When I display the order ID to the user, I want to somehow mask/obfuscate it.

Why?

  • So at first glance, it is obvious to admin users what the number refers to (orders start with 10, customers start with 20 etc)
  • To hide, at first glance, that this is only my 4th order.

Based on this this answer, I want the masked/obfuscated order id to:

  • Be only numbers
  • Consistent length (if possible)
  • Not cause collisions
  • Be reversible so I can decode it and get the original ID

How would I acheive this in PHP? It doesn't have to be very complex, just so at first glance it's not obvious.

Was it helpful?

Solution 3

Probably the simplest way is to just generate a long random string and use it instead of the auto-increment ID. Or maybe use it alongside the auto-increment ID. If the string is long enough and random enough, it will be unique for every record (think of GUIDs). Then you can display these to the user and not worry about anything.

OTHER TIPS

I think you can use XOR operator to hide "at first glance" for example (MySQL example):

(id*121) ^ 2342323

Where 2342323 and 121 are "magic" numbers - templates for the order number. To reverse:

(OrderNum ^ 2342323)/121

Additional advantage in this case - you can validate OrderNumber (to avoid spam or something like this in online form) if (OrderNum ^ 2342323) is divided by 121 with no remainder.

SQLFiddle demo

A little bit late, but Optimus (https://github.com/jenssegers/optimus) does exactly what is here asked for.

$encoded = $optimus->encode(20); // 1535832388
$original = $optimus->decode(1535832388); // 20

Only the initial setup is a bit weird (generate primenumbers)

Can it help?

echo hexdec(uniqid());

Off course you should store this value at db, at the same row with order id.

Just converting a ID into something like HEX might not give you the result what you like. Moreover its still easy 'guessable'

I would a a extra ID column (i.e. order_id). Set a unqi. index. Then on_creation use one of the following mysql functions:

SHA1(contcat('ORDER', id))
MD5(contcat('ORDER', id))
SHA1(contcat('ORDER', id, customer_id))
MD5(contcat('ORDER', id, customer_id))

UUID()

// try this in your mysql console
SELECT UUID(), SHA(CONCAT('ORDER',10)), SHA1(1);

You could (as in the example), add a simple text prefix like 'order'. Or even combine them. However i think UUID() would be easiest.

Implementation depends a bit on what you prefer you could use a stored procedure) or incorporate it in your model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top