Reputation: 245
I am trying to perform the following using a Perl script:
To do so, after a long research on the internet, I came up with the following lines:
# Initialize my variable: in my function, this is passed as input
$str = '5B CD 02 01 10';
# Extract the two characters to form a Byte
$OldByte_str = substr($str,0,2);
# Convert to binary. Supposed to give '0101 1011'
$PDM_OldBits = ( "Binary: %b\n", $PDM_OldByte );
# Replace two bits.Supposed to give '01**10** 1011'
substr($PDM_OldBit,2,2)= '10';
# Convert back to Bytes. Supposed to give'6B'
$NewByte_str= sprintf("0x%x", stringdecimal(arraystring($PDM_OldBits)));
# Substitute back into the original Bytes string.
# Supposed to give: '**6B** CD 02 01 10'
substr($str,0,2)= $PDM_NewByte;
with:
sub stringdecimal {
return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
sub arraystring {
my $string = join('', @_);
return $string;
}
However, the conversion to binary is not taking place; thus i am also not able to check the rest of the code.
As a beginner to Perl, I am asking this question here - in case someone has some hints or solutions to my problem.
Upvotes: 3
Views: 1665
Reputation: 3032
Here's an alternative solution - using only pack()
and unpack()
and one call to substr()
(no sprintf()
). It will modify each value in the array. (If you don't want that just take out the for()
loop and replace $_
with $bytes[0]
.)
use strict;
use warnings;
use feature('say');
my $str = '5B CD 02 01 10';
my ($orig, $bits, $hex);
my @bytes = split(/ /, $str);
for (@bytes) {
$bits = unpack('B8', chr(hex($_)));
$orig = $bits; # for 'debugging'
substr($bits, 2, 2) = '10';
say $orig . ' -> ' . $bits;
$hex = unpack('H2', pack('B8', $bits));
say $_ . ' -> ' . uc($hex);
}
Output ...
01011011 -> 01101011
5B -> 6b
11001101 -> 11101101
CD -> ed
00000010 -> 00100010
02 -> 22
00000001 -> 00100001
01 -> 21
00010000 -> 00100000
10 -> 20
Using substr($str, 0, 2);
to extract the bytes of interest - aside from being unwieldy - is potentially unreliable. If there is inconsistent white spacing in the input, for example, then it could extract 'B '
instead of '5B'
or ' C'
instead of 'CD'
. That's why I split the string in to bytes using split()
instead.
Upvotes: 2
Reputation: 50677
strict
and warnings
will always give you hints when mistyping something.
use strict;
use warnings;
sub stringdecimal {
# return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
return oct("0b" . shift);
}
my $str = '5B CD 02 01 10'; #Initialize my variable:in my function, this is passed as input
my $OldByte_str = substr($str,0,2); #extract the two characters to form a Byte
my $PDM_OldBits = sprintf( "%b", hex($OldByte_str) );#Convert to binary. Supposed to give '0101 1011'
substr($PDM_OldBits,1,2)= '10'; #Replace two bits.Supposed to give '01**10** 1011'
my $NewByte_str= sprintf("%X", stringdecimal($PDM_OldBits)); #Convert back to Bytes. Supposed to give'6B'
substr($str,0,2)= $NewByte_str; #Substitute back into the original Bytes string.Supposed to give: '**6B** CD 02 01 10'
print $str, "\n";
Upvotes: 2