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.
void scramble(char*trg,char*src
{
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
$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;
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
# -------------------------
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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;
$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;
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 ?
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 ?
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;
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;
ASKER
LoL, I needed to save back the array
$result = pack "C*",@trg;
it only had pack "C*",@trg;
Splitting the points, all helped.
$result = pack "C*",@trg;
it only had pack "C*",@trg;
Splitting the points, all helped.
ASKER
# --------------------------
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 //.