Alex Rivera | Logout

Integer ID obfuscation techniques

Asked 2010-04-02T07:12:31.313
12

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?

Edit
Report

3 Answers

7

I derived an idea from Pearson hashing which will work for arbitrary inputs as well, not just 32-bit integers. I don't know if this is the exact same as Greg answer, but I couldn't get at what he meant. But what I do know is that the memory requirements are constant here. No matter how big the input, this is still a reliable obfuscation/encryption trick.

For the record, this method is not hashing, and it does not have collisions. It's a perfectly sound method of obfuscating a byte string.

What you need for this to work is a secret key _encryptionTable which is a random permutation of the inclusive range 0..255. You use this to shuffle bytes around. To make it really hard to reverse it uses XOR to mix the byte string a bit.

public byte[] Encrypt(byte[] plaintext)
{
    if (plaintext == null)
    {
        throw new ArgumentNullException("plaintext");
    }
    byte[] ciphertext = new byte[plaintext.Length];
    int c = 0;
    for (int i = 0; i < plaintext.Length; i++)
    {
        c = _encryptionTable[plaintext[i] ^ c];
        ciphertext[i] = (byte)c;
    }
    return ciphertext;
}

You can then use the BitConverter to go between values and byte arrays or some convert to base 64 or 32 to get a textual representation. Base 32 encoding can be URL friendly if that's important. Decrypting is as simply as reversing the operation by computing the inverse of the _encryptionTable.

    public byte[] Decrypt(byte[] ciphertext)
    {
        if (ciphertext == null)
        {
            throw new ArgumentNullException("ciphertext");
        }
        byte[] plaintext = new byte[ciphertext.Length];
        int c = 0;
        for (int i = 0; i < ciphertext.Length; i++)
        {
            plaintext[i] = (byte)(_decryptionTable[ciphertext[i]] ^ c);
            c = ciphertext[i];
        }
        return plaintext;
    }

You can also do other fun things if you'r

answered 2010-04-02T09:08:44.140
0

You could play with the bitpatterns of the number - eg rotates and swaps on the bits. That will give you a way to move between a number of say 26 bits and another number of 26 bits that won't be immediately obvious to a human observer. Though its by no means "secure".

answered 2010-04-02T09:14:38.050
-2

Just get a MD5/SHA1 hash of the integer's byte representation. You are guaranteed not to get collisions.

answered 2010-04-02T09:04:03.213

Your Answer