Solved

A simple perl function needed

Posted on 2003-10-23
14
194 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 25 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 25 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
 
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 25 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 25 total points
ID: 9607429
$v = chr( (ord($c) + ord($o)) %256);

This manipulation is starting to look expensive.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 84

Accepted Solution

by:
ozo earned 150 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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Perl Tutorial 6 127
hard perl script 16 146
stftime format 4 51
what are these modules in perl script 4 84
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

708 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now