Take the 2-minute tour ×

My problem is that I've got URL access keys that look like "Bd333333d". I need the string length to be no longer than the original, but may be shorter. I want to convert/obfuscate the duplicate characters in the string and be able to convert them back to the original.

share|improve this question
You could go with the first solution, and escape the naturally occurring pipes, how small do you need to make it? Maybe translating it to binary, then using solution one would make it smaller? –  Ben Apr 27 '11 at 4:48
If people can still see the encoded keys, and use them instead - what security gain is there? –  Orbling Apr 27 '11 at 4:49
@mazzzzz: Basically just scrambling the string to avoid duplicate chars, but keeping the same string length. –  vanarie Apr 27 '11 at 4:55
Your first idea is known as Run-length encoding. –  Josh Rosen Apr 27 '11 at 5:01
So what is the point? I assume you want to add a bit of privacy? –  Ben Apr 27 '11 at 5:23
show 2 more comments

3 Answers

PHP can already do string compression, so why would you want to come up with your own algorithm? See this post for some excellent suggestions of combining gzip compression with urlencoding.

You don't say whether you're storing these strings internally or using them as part of a URL. If it's the former, then this is even easier because you can just store it as the much more compact binary.

share|improve this answer
add comment

This is a good task for preg_replace_callback

$str = 'Bd333333dddd';

function shorten( $str ) {
    return preg_replace_callback(
        function( $matches ) {
            return sprintf( '%s.%s', $matches[1], strlen( $matches[0] ) );
share|improve this answer
add comment

UPDATE: Thanks for your help! After doing some work on the hybrid ROT13 concept, I came up with something that works for me. Sorry to be lame and post my own solution, but here it is:

function ROT_by_strpos($s,$type='in'){

$index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

for ($n = 0; $n<strlen($index); $n++){
    $k[] = substr( $index,$n ,1);

if($type == 'out'){
    $k = array_reverse($k);

$rot = '';
$count = 1;
$len = strlen($s);
for ($n = 0; $n<strlen($s); $n++){
    $key_in[] = substr( $s,$n ,1);

    $key = array_search($key_in[$i], $k)+1;

    if($type == 'in'){
        if($key+$i > count($k)){
            $rev = $key+$i - count($k);
            $new_key = $rev;
            $new_key = $key+$i;
        if($key+$i >= count($k)){
            $adv = $key+$i - count($k);
            $new_key = $adv;
            $new_key = $key+$i;

    $rot .= $k[$new_key];

return $rot;

This assumes that possible chars are from $index and code string length <= 10 chars long.


$key = "Bd333333d";

$in = ROT_by_strpos($key,'in');

$out = ROT_by_strpos($in,'out');

echo "$key - $in - $out"; //Bd333333d - Cf6789ABm - Bd333333d

There's probably a more elegant way to do this, but it does work. Any feedback or improvements would be appreciated if you want to add something. :)

share|improve this answer
add comment

Your Answer


