You could probably do something like this:

$ echo "ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAAB +C BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBC ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCC" | per +l -le' use Data::Dumper; $Data::Dumper::Useqq = 1; my %alphabet = qw/ A 00 B 01 C 11 /; my %rev_alpha = reverse %alphabet +; while ( <> ) { chomp; print length(), " ", $_; # compress my $data = pack "B*", join "", map $alphabet{ $_ }, split //; print length $data, " ", Dumper $data; # decompress my $uncp = join "", map $rev_alpha{ $_ }, map /../g, unpack "B*", +$data; print length $uncp, " ", $uncp, "\n"; } ' 63 ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAABC 16 $VAR1 = "\27p\1w?\0000\1U\0\24\0\1\177<\34"; 64 ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAABCA 63 BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBC 16 $VAR1 = "\177p\301\\\17\0000\1U\0\24\0\1\177<\\"; 64 BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBCA 63 ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCC 16 $VAR1 = "\37T\1G1\377\360\1u\377\0\0\0?<\374"; 64 ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCCA

One of the problems with this is that "00" is a valid value so you get extra "A"s padding the right hand side of the string on decompression.

If you change the alphabet to:

01 A 10 B 11 C

It will decompress properly:

$ echo "ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAAB +C BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBC ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCC" | per +l -le' use Data::Dumper; $Data::Dumper::Useqq = 1; my %alphabet = qw/ A 01 B 10 C 11 /; my %rev_alpha = reverse %alphabet +; while ( <> ) { chomp; print length(), " ", $_; # compress my $data = pack "B*", join "", map $alphabet{ $_ }, split //; print length $data, " ", Dumper $data; # decompress my $uncp = join "", map $rev_alpha{ $_ }, map /../g, unpack "B*", +$data; print length $uncp, " ", $uncp, "\n"; } ' 63 ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAABC 16 $VAR1 = "k\265V\273\177UuV\252UiUV\277}l"; 63 ABBCBCAAAAABBCBCACCCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCAABC 63 BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBC 16 $VAR1 = "\277\265\326\255_UuV\252UiUV\277}\254"; 63 BCCCBCAACAABBBCAAACCAAAAACAAAAABBBBBAAAAABBAAAAAAAABBCCCACCABBC 63 ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCC 16 $VAR1 = "o\251V\233v\377\365V\272\377UUU\177}\374"; 63 ABCCBBBAAAABBABCACABCCCCCCAAAAABBCBBCCCCAAAAAAAAAAAAACCCACCACCC

In reply to Re: How to efficently pack a string of 63 characters by jwkrahn
in thread How to efficently pack a string of 63 characters by baxy77bax

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.