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.
LVL 6
WxWAsked:
Who is Participating?
 
ozoCommented:
my @trg;
my @rkey = unpack"C*","The Key";
my $ll = @rkey;
my @unt = unpack"C*",$source_buffer;

for $x( 0 .. $#unt ) {
  $trg[$x] = $unt[$x] + $rkey[$x % $ll];
 }
return pack"C*",@trg;
0
 
fantasy1001Commented:
try to change this:
my @rkey = split / /, "The key";
my @unt = split / /, $source_buffer;
my $len = @unt;   # should return the length
$trg[$_] = map { $unt[$_] + $rkey[$_ % $len] } 1..@unt;

OR
my @rkey = split / /, "The key";
my @unt = split / /, $source_buffer;
foreach (1..$#unt){
   $trg[$_] = $unt[$_] + $rkey[$_ % $#unt];
}

NOTE: I am not sure whether $_ % $#unt will return the remaining or not.

Try first. Thanks & cheers.
0
 
ultimatemikeCommented:
Change the lines to:


my @rkey = split //, "The Key";

and

my @unt = split //, $source_buffer;



What this will do is split the strings and store each character as an element of an array. Perhaps not the most efficient way of doing it, but it should make operating on the individual characters easy.  Then when you want to print out the result,

print join('', @trg);



Also I noticed that in your method you set $cot[$x].  Should that be $trg[$x]?

0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
WxWAuthor Commented:
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 //.
0
 
ultimatemikeCommented:
 $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;
0
 
BioICommented:
if you want to split a string in different charachters, you can *not* do this by:
my @rkey = split //,$uidkey;
my @unt = split //,$untouch;

the way I usually do it, is splitting the string by adding different charachters between the different charachters, end then split them bases on this charachter e.g. "-"

#### script ###
my @trg;
$rkey =~ s/(?<=.)(?=.)/$1-/g; # inserting "-"
print "rkey -> $rkey\n";
@rkey = split /-/, $rkey;  # split into different charachters based on "-"
foreach $number (@rkey) {
    print "$number\n";
}
my $ll = @rkey;
print "length -> ", $ll, "\n";

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

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

my $result = join('', @trg);
0
 
WxWAuthor Commented:
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?

0
 
jmcgOwnerCommented:
$v = chr( (ord($c) + ord($o)) %256);

This manipulation is starting to look expensive.
0
 
WxWAuthor Commented:
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.
0
 
jmcgOwnerCommented:
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;


0
 
WxWAuthor Commented:
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 ?




0
 
WxWAuthor Commented:
Also, the C++ routine works the same way with both unsigned and signed variables.
0
 
jmcgOwnerCommented:
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;
0
 
WxWAuthor Commented:
LoL,  I needed to save back the array

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

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

Splitting the points, all helped.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.