in reply to Bit-vector compression

my $i = int(rand(length($str)-1));

You have an off-by-one problem there.

Say that $str has a length of 8 and so has characters at positions 0 through 7.

length($str)-1 will produce random numbers in the range 0 through 6, one less than the length of the string.

Update:

This produces the same result as your pack_str subroutine:

sub pack_str { my ( $s ) = @_; return pack 'B*', $s; }