views:

287

answers:

1

This was not written by me; it was written by someone who passed it down to me. I lost contact with the author of the code. I have been using this code for a few years and just now realized this error. It seems that the letter sequence rkey1 messes up the output.

For example turkey1 outputs as decryption as tur79y1. This Perl code should output turkey1 and not tur79y1:

$String = "turkey1";
$e = &encode_escaped(&palace_encrypt($String));
$d = &palace_decrypt(&decode_escaped("'\"".$e."\"'"));
print $d."<br>\n";

KEY REMOVED BY OWNER


sub palace_decrypt
{
    local $lastchar = 0;
    local $rc = 0;
    local @bs;
    for($i=length($_[0])-1; $i>=0; $i--) {
     local $tmp = ord(substr($_[0], $i, 1));
     $bs[$i] = $tmp ^ $palace_key[$rc++] ^ $lastchar;
     $lastchar = $tmp ^ $palace_key[$rc++];
     }

    return join("", map { chr($_) } @bs);
}

sub decode_escaped
{
    $_[0] =~ m/\"(.*)\"/;
    local $str = $1;
    $str =~ s/\\\\/\0/g;
    $str =~ s/\\"/"/g;
    $str =~ s/\\(..)/pack("c",hex($1))/ge;
    $str =~ s/\0/\\/g;
    return $str;
}


sub palace_encrypt
{
    local $lastchar = 0;
    local $rc = 0;
    local @bs;
    for($i=length($_[0])-1; $i>=0; $i--) {
     local $b = ord(substr($_[0], $i, 1));
     $bs[$i] = $b ^ $palace_key[$rc++] ^ $lastchar;
     $lastchar = $bs[$i] ^ $palace_key[$rc++];
     }
    return join("", map { chr($_) } @bs);
}

sub encode_escaped
{
    local $str = $_[0];
    $str =~ s/\\/\\\\/g;
    $str =~ s/([^A-Za-z0-9\.\\])/sprintf("\\%2.2X", ord($1))/ge;

    return $str;
}
+10  A: 

Your problem is that your decode_escaped does not exactly undo what encode_escaped did. Replace it with the following and that should fix your problem.

sub decode_escaped
{
    $_[0] =~ m/\"(.*)\"/;
    local @str = split /(\\\\)/, $1;
    foreach (@str) {
        s/\\"/"/g;
        s/\\(..)/chr(hex($1))/ge;
        s/\\\\/\\/;
    }
    return join '', @str;
}
Inshallah
Works perfect.Thanks
BHare