crashtest has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I am writing some code that takes a number of pieces of data and packages them up into one large chunk. I am using pack to do this, and it works fine in most cases. E.g.,

my $eight_bit_piece = 255; my $other_eight_bit_piece = 255; my $sixteen_bit_piece = 8; my $packaged_data = pack("CCn", $eight_bit_piece, $other_eight_bit_piece, $sixteen_bit_piece); # Gives me 11111111 11111111 0000000000001000 as desired

However, I don't know what to do when my individual pieces of data don't divide cleanly into 8-bit chunks. For example, I want to assemble a 16-bit word from two six-bit and one four-bit chunks:

my $piece_one_six_bits = 12; # 001100 my $piece_two_six_bits = 12; # 001100 my $piece_three_four_bits = 5; # 0101 # What now?

I have come up with a solution...

my $packaged_data = pack("n", $piece_one_six_bits << (6 + 4) | $piece_two_six_bits << 4 | $piece_three_four_bits );
... but it doesn't feel right. I am trying to avoid bitwise operations. Isn't this work pack should be able to do? Can anybody point me in the right direction with this?

Thanks in advance for your help.

Replies are listed 'Best First'.
Re: Using pack with data of odd lengths
by diotalevi (Canon) on Sep 22, 2006 at 23:52 UTC

    Your other tools are using pack/unpack to convert bits into perl strings of bits like "1..." and "0..." and using vec() to toggle specific bits. vec() only works when your chunks are powers of two.

    my $piece_one_six_bits = '001100'; my $piece_two_six_bits = '001100'; my $piece_three_four_bits = '0101'; # Ugly, eh? my $packaged_data = pack 'B*', "$piece_one_six_bits$piece_two_six_bits +$piece_three_four_bits";

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Using pack with data of odd lengths
by ikegami (Patriarch) on Sep 23, 2006 at 05:18 UTC

    Isn't this work pack should be able to do?

    pack's main purpose is to convert between Perl and machine numbers. vec is the function designed for bit work. Unfortunately, vec only works with fields which are powers of 2 in size.