Reputation: 13072
I'm decoding a fixed-width binary file in perl. One of the fields is 1 byte in length and the 8 bits are encoded such that:
The 7th Bit unused, The 0-4th bit is used to indicate Field1. The 5-6th Bit is used to indicate Field2.
For example the field 0x27
will give Field1 = 7
, Field2 = 1
.
I'm reading all the fields into a hash table called raw{}
and then decoding the values into another hash called processed{}
.
The code (only shown for this one byte) is
while (read(FILE, $buff, 559)) {
%raw = (); # Hash for first-pass extractions
%processed = (); # Hash for cleaned up values, for output
(
......
$raw{'Field12'},
......
)= unpack('
.....
H2
.....
h*',$buff);
$prcoessed{'Field1'} = unpack("B8", pack("H8", $raw{'Field12'})) & 0x1f;
$prcoessed{'Field2'} = (unpack("B8", pack("H8", $raw{'Field12'})) >> 5) & 0x3;
However, I don't get the desired values. I get $prcoessed{'Field1'} = 15
and $prcoessed{'Field2'} = 3
. Where am I going wrong?
Upvotes: 0
Views: 97
Reputation: 242443
0x1f
is a number, you need to transform it into a character.
Instead of packs and unpacks, you can use ord
and chr
:
#!/usr/bin/perl
use warnings;
use strict;
my $char = chr 0x27;
my $field1 = $char & chr 0x1f;
my $field2 = $char & chr 0x60;
$field2 = chr(ord($field2) >> 5);
print ord, "\n" for $field1, $field2;
The same script using pack
and unpack
:
my $char = pack 'C', 0x27;
my $field1 = $char & pack 'C', 0x1f;
my $field2 = $char & pack 'C', 0x60;
$field2 = pack 'C', unpack('C', $field2) >> 5;
print unpack('C', $_), "\n" for $field1, $field2;
Upvotes: 1