views:

36

answers:

2

Dear all,

I can't figure out how to optimally do the following in PHP: In a database, I have messages with a unique ID, like 19041985. Now, I want to refer to these messages in a short-url service but not using generated hashes but by simply 'calculate' the original ID.

In other words, for example: http://short.url/sYsn7 should let me calculate the message ID the visitor would like to request.

To make it more obvious, I wrote the following in PHP to generate these 'alphanumeric ID versions' and of course, the other way around will let me calculate the original message ID.

The question is: Is this the optimal way of doing this? I hardly think so, but can't think of anything else.

$alphanumString = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_';
for($i=0;$i < strlen($alphanumString);$i++)
{
 $alphanumArray[$i] = substr($alphanumString,$i,1);
}



$id = 19041985;

$out = '';
for($i=0;$i < strlen($id);$i++) {

 if(isset($alphanumString["".substr($id,$i,2).""]) && strlen($alphanumString["".substr($id,$i,2).""]) > 0) {
  $out.=$alphanumString["".substr($id,$i,2).""];
 } else {
  $out.=$alphanumString["".substr($id,$i,1).""];
  $out.=$alphanumString["".substr($id,($i+1),1).""];
 }
 $i++;
}

print $out;
+1  A: 
echo trim(base64_encode(pack("L", 19041987)), "=");
print_r(unpack("L", base64_decode("w44iAQ")));
  • Pack changes the number into four bytes, which is very short but unreadable.
  • Base64_encode changes the four bytes into some more human-readable characters.
  • It appends some = characters, which are not needed.

If you do base64_encode(19041987), you get the encoding for the string "19041987", which is not shorter.

Sjoerd
This works for the given example, but when the ID is larger (let's say 9876543210) this doesn't work anymore: It gives '6hawTA' as string but returns 1286608618 when I use your example. - What is the maximum number for this to work? I use BIGINT (20) to store these ID's so that is way to large when using base64, right?
Glooh
A: 

You should never use a function inside a for statement since it's played during every loop.

For instance your

for($i=0;$i < strlen($alphanumString);$i++)
{
 $alphanumArray[$i] = substr($alphanumString,$i,1);
}

should be

var $alphaLength = strlen($alphanumString);
for($i=0;$i < $alphaLength;$i++)
{
 $alphanumArray[$i] = substr($alphanumString,$i,1);
}
Kaaviar
You are doing micro-optimization. Strings are already accessible as arrays. Building this $alphanumArray is unnecessary.
Sjoerd
Actually on small arrays, there a signifiant gain using this method. But I do agree it's micro-optimization.
Kaaviar