Client has an simple increasing order number (1, 2, 3…). He wants end-users to receive an 8- or 9- digit (digits only — no characters) ‘random’ number. Obviously, this ‘random’ number actually has to be unique and reversible (it’s really an encryption of the actualOrderNumber).
My first thought was to just shuffle some bits. When I showed the client a sample sequence, he complained that subsequent obfuscOrderNumbers were increasing until they hit a ‘shuffle’ point (point where the lower-order bits came into play). He wants the obfuscOrderNumbers to be as random-seeming as possible.
My next thought was to deterministically seed a linear congruential pseudo-random-number generator and then take the actualOrderNumber th value. But in that case, I need to worry about collisions — the client wants an algorithm that is guaranteed not to collide in at least 10^7 cycles.
My third thought was ‘eh, just encrypt the darn thing,’ but if I use a stock encryption library, I’d have to post-process it to get the 8-or-9 digits only requirement.
My fourth thought was to interpret the bits of actualOrderNumber as a Gray-coded integer and return that.
My fifth though was: ‘I am probably overthinking this. I bet someone on StackOverflow can do this in a couple lines of code.’
Pick a 8 or 9 digit number at random, say 839712541. Then, take your order number’s binary representation (for this example, I’m not using 2’s complement), pad it out to the same number of bits (30), reverse it, and xor the flipped order number and the magic number. For example:
To get the order numbers back, xor the output number with your magic number, convert to a bit string, and reverse.