Hi
snellm,
I think this is fun. What you actually need to do, is to
represent your data into just the bits that you need,
and hack these bits into 8-bits chunks (aka bytes),
and transform these bytes into usable characters. This
sounds like UUencoding. However, UUencoding uses too many
characters.
CPAN sayz: Convert:UU
I would suggest that you take that module, and remorph
it a little bit to use only a range of usable characters.
Wait, I'm doing a perl -MCPAN -e shell, install Convert::UU.
Hmm.. I see this package just uses pack("u",$string)
internally. Well, the search continues. It is obvious
that I haven't used pack before!
Let's play a little bit. Maybe you want 16 different modes,
and 2 16 bit integers for your Area cq Subarea. That adds
up to 36 bits (2**4=16). If we use A..Za..z0..9 *and* '%',
'-' we have 64 possibilities, or 6 bit. Than we can cram
everything in 6 characters.
The encoder must pack the stuff:
sub encode{
my $mode = shift;
my $area = shift;
my $subarea = shift;
my $str;
my $bitstr=unpack("b4",pack("v",$mode)).
unpack("b16",pack("v",$area)).
unpack("b16",pack("v",$subarea));
for (0..5){
my $val=unpack('c',pack('b6',substr($bitstr,$_*6,6)));
if ($val<10){
$str.=pack('c',$val+48);
}elsif ($val<36){
$str.=pack('c',$val+65-10);
}elsif ($val<62){
$str.=pack('c',$val+97-36);
}elsif ($val == 63){
$str.=pack('c',37);
}elsif ($val == 64){
$str.=pack('c',45);
}
}
$str;
}
sub decode{
my $str = shift;
my $bitstr;
for (split //, $str){
my $item = unpack('c', $_);
for ($item){
$val = 64, last if $item == 45;
$val = 63, last if $item == 37;
$val = $item-97+36, last if $item >= 97;
$val = $item-65+10, last if $item >= 65;
$val = $item-48, last if $item >= 48;
}
$bitstr .= unpack("b6",pack("v",$val));
}
$mode = unpack('c',pack('b4',substr( $bitstr,0,4)));
$area = unpack('v',pack('b16',substr( $bitstr,4,16)));
$subarea = unpack('v',pack('b16',substr( $bitstr,20,16)));
($mode, $area, $subarea);
}
$encoded=encode(15,13,13);
$decoded=join ', ', decode( $encoded );
print "Encoded: $encoded\nDecoded array: $decoded\n";
Some reverse coding for the decoder, but I'm too lazy
for that. Is this what you want to do?
Disclaimer: This is my first use of pack,
so I'm not sure I'm doing the right thing, let alone
the efficient thing. Please correct me!
Cheers,
Jeroen
"We are not alone"(FZ)
Update: Made the decode sub as well. Tested it.
Discovered some differences between running at linux and
at mac at home, so used 'v' for packing stuff.
Now I've moved this code into a module, for generalized
use. You can find it here.
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.