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