Ascari Ascari - 7 months ago 22
Perl Question

Writing (and reading) bits to binary files in Perl + EOF handling

I have two related problems (in Perl):


  1. Write data to binary files, in the format: single bit flag followed by 8 bits

  2. Read back the same format



I tried this (and other variations but for the life of me I can't figure this out):

binmode(OUT);
my $bit = pack("B1", '1');
my $byte = pack("H2", "02");
print OUT $bit . $byte;


Using a hex editor, I see I get 16 bits:

1000000000000020


What I want is 9 bits:

100000020


Also: Suppose I write out two of these patterns. That means I end up with 9 + 9 = 18 bits. I am not sure how to handle the last byte (padding?)

This is to compress and uncompress files, with space at premium. I was hoping there would be some simple idiomatic way to do this that I am not aware of.

Answer

You can use Bit::Vector to manage your bits and conversion with some more ease,

use Bit::Vector;

my $bit = Bit::Vector->new_Bin( 1, '1' );

my $byte     = Bit::Vector->new_Bin( 8, '00000010' );
my $byte_9   = Bit::Vector->new_Bin( 9, '000000010' );
my $nineBits = Bit::Vector->new_Bin( 9, '100000000' );
my $carry    = Bit::Vector->new_Bin( 9, '000000000' );
my $ORed     = Bit::Vector->new_Bin( 9, '000000000' );
my $added    = Bit::Vector->new_Bin( 9, '000000000' );


$ORed->Union($nineBits,$byte_9);

print "bit: 0x". $bit->to_Hex(). "\n";
print "byte 2: 0x". $byte->to_Hex(). "\n";
print "nineBits: 0x". $nineBits->to_Hex(). "\n";
print "nineBits: 0x". $nineBits->to_Bin(). "\n";
print "ORed bit and byte 0x". $ORed->to_Dec(). "\n";

open BINOUT, ">out.bin"
    or die "\nCan't open out.bin for writing: $!\n";

binmode BINOUT;

print BINOUT pack ('B*', $ORed->to_Bin()) ."\n"

Here's the output

>perl bitstuff.pl
bit: 0x1
byte 2: 0x02
nineBits: 0x100
nineBits: 0x100000000
ORed bit and byte 0x-254
>cat out.bin 
\201^@
Comments