Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

A simple perl function needed

Posted on 2003-10-23
14
Medium Priority
?
248 Views
Last Modified: 2010-05-18
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.
0
Comment
Question by:WxW
  • 6
  • 3
  • 2
  • +3
14 Comments
 
LVL 5

Assisted Solution

by:fantasy1001
fantasy1001 earned 100 total points
ID: 9605771
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
 
LVL 2

Assisted Solution

by:ultimatemike
ultimatemike earned 100 total points
ID: 9605785
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
 
LVL 6

Author Comment

by:WxW
ID: 9606035
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Expert Comment

by:ultimatemike
ID: 9606291
 $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
 
LVL 3

Assisted Solution

by:BioI
BioI earned 100 total points
ID: 9606348
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
 
LVL 6

Author Comment

by:WxW
ID: 9607231
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
 
LVL 20

Assisted Solution

by:jmcg
jmcg earned 100 total points
ID: 9607429
$v = chr( (ord($c) + ord($o)) %256);

This manipulation is starting to look expensive.
0
 
LVL 85

Accepted Solution

by:
ozo earned 600 total points
ID: 9607768
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
 
LVL 6

Author Comment

by:WxW
ID: 9608263
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
 
LVL 20

Expert Comment

by:jmcg
ID: 9608529
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
 
LVL 6

Author Comment

by:WxW
ID: 9608592
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
 
LVL 6

Author Comment

by:WxW
ID: 9608628
Also, the C++ routine works the same way with both unsigned and signed variables.
0
 
LVL 20

Expert Comment

by:jmcg
ID: 9608839
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
 
LVL 6

Author Comment

by:WxW
ID: 9608943
LoL,  I needed to save back the array

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

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

Splitting the points, all helped.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question