views:

115

answers:

4

Hi,

For a variety of stupid reasons, the maximum length of a given form variable that we are posting to an external server is 12 characters.

I wanted to obscure that value with md5, but obviously with 12 characters that isn't going to work. Is there a cipher with an already-made PHP function which will result in something 12 characters or less?

The security and integrity of the cipher isn't super important here. My last resort is to just write a function which moves each letter up or down an ascii value by x. So the goal isn't to obscure it from a cryptography expert, but just to not post it in plain text so a non-technical worker looking at it won't know what it is.

Thanks for any advice.

+4  A: 

If you just need a hash, you can still use the first 12 characters from the md5 hash.

substr(md5($yourString, 0, 12)
Colin Hebert
I was just typing the very same!
adam
I should clarify that we still need to decode it. There could be a case where the first 12 characters of one md5 are the same as another.
tiredofcoding
@tiredofcoding: MD5, as any other hash, is a one-way function: you *can't* decode it. What you want is a cipher, not a hash.
casablanca
I know that. What I'm saying is that we'll maintain the values of each piece of data we encode with md5. So we'll know that value x = md5 value y.
tiredofcoding
@tiredofcoding: Then you may consider picking out different parts of the MD5 hash to reduce chances of collision, or split the MD5 into four 8-character strings and fold them somehow into a single string.
casablanca
"value x = md5 value y" and first12LettersFrom(value x) = first12LettersFrom(md5 value y) too. I don't really see the problem here.
Colin Hebert
but what about the chances of the first 12 characters being the same as another?
tiredofcoding
Every hash function has collisions. If you want to avoid absolutely collisions, you need to cypher and compress your String so it fit in 12 characters.
Colin Hebert
@casablanca That won't improve collision odds - any well designed hash function will have good distribution over any subset.
Nick Johnson
@tiredofcoding With 12 hexadecimal characters, you have 48 bits of hash. According to the birthday paradox, you'd expect a collision after about 2^24 hashes - 16 million of them. If you use base64, then your 12 characters encode 9 bytes, which is 72 bits, for an expected collision after about 2^36 or 68 billion hashes.
Nick Johnson
A: 

Try crc32() maybe?

Alex Howansky
A: 

this is just 7 characters long:

echo str_pad(base_convert(sprintf('%u',crc32($str)),10,36),7,'0',STR_PAD_LEFT);

it converts crc-32 long integer to base 36.

stillstanding
A: 

This is an addition to this answer.

The answer proposes to take the first twelve characters from a 32 character representation of md5. Thus 20 characters of information will be lost - this will result in way more possible collisions.

You can reduce the loss of information by taking the first twelve characters of a 16 character representation (the raw form):

substr(md5($string, true), 0, 12);

This will maintain 75% of the data, whereas the use of the 32 char form only maintains 37.5% of the data.

nikic