my %charmap = ( A => '00', C => '01', G => '10', T => '11', ); sub packACGT { ( my $in = shift ) =~ s/(.)/$charmap{$1}/ge; print length $in, ':', length( $in ) % 8; pack 'Cb*', ( 0, 6, 4, 2 )[ length( $in ) % 8 / 2 ], $in; } my %digmap = ( '00' => "A", '01' => "C", '10' => "G", '11' => "T", ); sub unpackACGT { my( $len, $out ) = unpack 'Cb*', shift; print $len; substr( $out, -$len ) = '' if $len; $out =~ s/(..)/$digmap{$1}/ge; return $out; } my $string = $ARGV[0] || 'GATTACCCC'; print length( $string ), ':', $string; my $compressed = packACGT( $string ); print length( $compressed ), ':', "'$compressed'"; my $decompressed = unpackACGT( $compressed ); print length( $decompressed ), ':', $decompressed;