Link to home
Start Free TrialLog in
Avatar of WxW
WxW

asked on

A simple perl function needed

I have a very simple function that takes a string and scrambles itwith a password and a given password length:

void scramble(char*trg,char*src,int len,char*pwd,int pwdlen)
   {
   for (int x = 0 ; x < len ; x ++)
      {
      trg[x] = src[x] + pwd[x % pwdlen];
      }
   }

I tried to do that in perl, without success.

my @trg;
my @rkey = "The Key";
my $ll = length(@rkey);
my @unt = $source_buffer;

for($x = 0 ; $x < $ll ; $x++) {
  $cot[$x] = $unt[$x] + $rkey[$x % $ll];
 }
and then im trying to write @trg to a file, and only 2 bytes are written, where the length of _source_buffer (1000 bytes) should have been written.

Please help.
SOLUTION
Avatar of fantasy1001
fantasy1001

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of WxW
WxW

ASKER

I have now this one.
# -----------------------------
my @trg;
my @rkey = split //,$uidkey;
my @unt = split //,$untouch;
my $ll = length($untouch);

for($x = 0 ; $x < $ll ; $x++) {
  $trg[$x] = $unt[$x] + $rkey[$x % $ll];
  }

my $result = join('',@trg);

# -------------------------------
This fails. It stores in the @trg array a string that is mostly filled in with zeros. I think that the
  $trg[$x] = $unt[$x] + $rkey[$x % $ll];

line , fails to add 8-bit chars correctly . i.e. if the original char is 255 and the add value is 10 , the dest char should be 9 (265 - 256).

It also fails when I use / /, instead of //.
 $trg[$x] = $unt[$x] + $rkey[$x % $ll];



Correct me if I'm wrong - but this can place values > 255 in @trg.  Try changing it to:


$trg[$x] = ($unt[$x] + $rkey[$x % $ll] ) % 256;
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of WxW

ASKER

I have this one now.
# -------------------------
my $tlen = 925; # length of source_buffer
my $rkey = $uidkey;
$rkey =~ s/(?<=.)(?=.)/$1-/g; # inserting "-"
@rkey = split /-/, $rkey;  # split into different charachters based on "-"
my $ll = @rkey;

$source_buffer =~ s/(?<=.)(?=.)/$1-/g; # inserting "-"
# print "source_buffer -> $source_buffer\n";
@unt = split /-/, $source_buffer;  # split into different charachters based on "-"

print "\r\n\r\n";

for($x = 0 ; $x < $tlen ; $x++) {
    $c = @rkey[$x % $ll];
    $o = @unt[$x];
    $v = $c + $o; <<< THIS LINE FAILS
   
    print "$v";

------------
$unt has the original data, with len $tlen.
@rkey has the key OK .
$v = ($c + $o) % 256;
This line generates always a number in $v, and not a byte.
How can I add two bytes and convert them to a byte?

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of WxW

ASKER

Jmcg: That nearly worked, except that ord($o) returns 0 if $o = space (0x20). I haven't yet tested what ord returns if $o == 0.
How to fix that ?

ozo: It doesn't work at all, it returns names instead of characters.
That's strange. If I do:

$o = " ";
print ord($o), "\n";

my version of Perl prints

32

=========

As usual, Ozo is on exactly the right track. He does not even need to do modulo 256 if both input strings contain only characters less than 128. I wonder why his solution did not work for you. (Your original C routined did not need to do module 256 because the variables were declared 'char'.)

=========

BioI's claim about not using split with a null pattern to divide a string into an array of characters contradicts my experience. I believe 'unpack' with 'C*' is better, but splitting with a null string ought to work: it's even appears as an example in the Camel book;


Avatar of WxW

ASKER

Edit: Yes, ord() works. But the buffer is binary, it can contain any value from 0 to 255. Therefore, if there is a '-' inside the buffer, it kills it (using the split pattern with '-') , and that is where ord() returns 0, because the buffer has a 0 as well , instead of the original '-'


Ozo's method sends me results with numbers, e.g. the @trg[0] has the number "193" instead of the char with ascii value 193. Any option on how to fix that ?




Avatar of WxW

ASKER

Also, the C++ routine works the same way with both unsigned and signed variables.
Well, that's just another argument against using BioI's method.

To turn the @trg array back into an ordinary scalar string, you need to do the operation Ozo indicated:

  $result = pack 'C*', @trg;

If you want to keep it as a split up array, but of one-character strings, I guess you'd need to do something like:

  @trg = map { chr } @trg;
Avatar of WxW

ASKER

LoL,  I needed to save back the array

 $result = pack "C*",@trg;

it only had  pack "C*",@trg;

Splitting the points, all helped.