3

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.

vanarie
  • 439
  • 1
  • 5
  • 12
  • 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? – Jess Apr 27 '11 at 04:48
  • If people can still see the encoded keys, and use them instead - what security gain is there? – Orbling Apr 27 '11 at 04:49
  • @mazzzzz: Basically just scrambling the string to avoid duplicate chars, but keeping the same string length. – vanarie Apr 27 '11 at 04:55
  • Your first idea is known as [Run-length encoding](http://en.wikipedia.org/wiki/Run-length_encoding). – Josh Rosen Apr 27 '11 at 05:01
  • So what is the point? I assume you want to add a bit of privacy? – Jess Apr 27 '11 at 05:23
  • @Josh Rosen: I knew there must be a name for what I was thinking about.. "Run-length encoding"! :) Thanks for putting a word to it. – vanarie Apr 27 '11 at 05:26
  • Here's a post related to [RLE in PHP](http://stackoverflow.com/questions/2566764/encode-compress-sequence-of-repeating-integers) – vanarie Apr 27 '11 at 05:32

3 Answers3

0

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.

Community
  • 1
  • 1
dj_segfault
  • 11,957
  • 4
  • 29
  • 37
0

This is a good task for preg_replace_callback

$str = 'Bd333333dddd';

function shorten( $str ) {
    return preg_replace_callback(
        '~(.)\1+~',
        function( $matches ) {
            return sprintf( '%s.%s', $matches[1], strlen( $matches[0] ) );
        },
        $str
    );
}
Galen
  • 29,976
  • 9
  • 71
  • 89
0

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);
}

for ( $i = 0; $i < $len; $i++ ){
    $key = array_search($key_in[$i], $k)+1;

    if($type == 'in'){
        if($key+$i > count($k)){
            $rev = $key+$i - count($k);
            $new_key = $rev;
        }else{
            $new_key = $key+$i;
        }
    }else{
        if($key+$i >= count($k)){
            $adv = $key+$i - count($k);
            $new_key = $adv;
        }else{
            $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.

Usage:

$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. :)

vanarie
  • 439
  • 1
  • 5
  • 12