I'm looking for an easy and reversible method of obfuscating integer IDs. Ideally, I'd want the resulting obfuscation to be at most eight characters in length and non-sequential, meaning that the obfuscation of "1" should look nothing like the obfuscation for "2" and so on.
This isn't meant to be secure by any means, so this isn't a huge concern. Additionally, the integers I'll be obfuscating aren't large - between one and 10,000 - but I don't want any collisions, either.
Does anybody have any ideas for something that would fit this criteria?
XOR is a nice and fast way of obfuscating integers:
It's fast, and xor-ing again with the same number gives you back the original! The only trouble is, if an "attacker" knows any of the numbers, they can trivially figure out the xor mask... by xor-ing the result with the known original!
For example I (the "attacker") now that the 4th number in that list is an obfuscated "100". So I'll do:
... and now I've got the XOR mask and I can un-obfuscated any of the numbers. Happily there are trivial solution to that problem. Algoritmically alter the XOR mask. For example, if you need to obfuscate 1000 integers in an array, start with a XOR mask of "1234" and do increment the MASK with 4 for each number in the arrray.
Just get a MD5/SHA1 hash of the integer's byte representation. You are guaranteed not to get collisions.
Update May 2017
Feel free to use (or modify) the library I developed, installable via Nuget with:
This converts a non-negative id such as 127 to 8-character string, e.g. xVrAndNb, and back (with some available options to randomize the sequence each time it's generated).
Example Usage
Full documentation at: Github.
Old Answer
Just adding variety to an old answer. Perhaps someone will need it. This is an obfuscation class I made sometime back.
Obfuscation.cs - Github
You can use it by:
Cheers, hopefully it can be of use.
In case other people are interested, somebody adapted a 32-bit block cipher a few years back that's especially useful for this task.
There is also Perl and Ruby port of the above available:
If you need the result in 8 characters or less, you can use a hex or base64 representation.