[ILUG] urg...
Niall O Broin
niall at linux.ie
Sat Feb 2 16:02:21 GMT 2002
On Fri, Feb 01, 2002 at 06:47:31PM +0000, kevin lyda wrote:
> ok, this is driving me nuts. i have a string in perl. let's call it $s.
> now i want to take $s 6 bits at a time and put each 6 bits (plus 32) into
> a byte in $e. in other words each 3 bytes of $s become 4 bytes in $e.
>
> anyone else play with bit shifting in perl? it doesn't seem to be
> working so far.
>
> this doesn't work and i feel like shooting it at this point:
>
> #!/usr/bin/perl
>
> $s = shift;
> $s .= "\0" x ((length($s) % 3)? 3 - (length($s) % 3): 0);
> $e = "";
> while (length($s) > 0) {
> $c = substr($s, 0, 3);
> $s = substr($s, 3);
> foreach $x (1...4){
> $e .= chr((ord(substr($c, 0, 1)) & 0xfc) + 32);
> $c <<= 6;
> }
> }
> $d = "";
> print("original: $s(".length($s).")\nencoded: $e\ndecoded: $d\n");
You've a Perl question, so here's a Perl one line answer which puts the command line
argument recoded into $result. If the argument isn't an integral multiple of
6 bits then the end of the result is undefined, but it'll be right as far as
it goes. Supply decent input :-) or code around it. Pack and unpack are
usually the answer when you're bit munging in Perl though I have to admit
that those terrible twins ALWAYS hurt my head.
Normal human beings may not like this but Perl programmers and Lisp people
should be happy enough with it :-)
#!/usr/bin/perl
$result = pack("B*", "0" . join "0", map { (/^1/ ? "10" : "01") . substr $_, 1 }
grep($_, split(/(......)/, unpack("B*", $ARGV[0]))));
# This is just a simple test / verification
print "INPUT ";
for (grep($_, split(/(......)/, unpack("B*", $ARGV[0])))) {
print " $_"
}
print "\nOUTPUT 0" . (join "0", map { (/^1/ ? "10" : "01") . substr $_, 1 }
grep($_, split(/(......)/, unpack("B*", $ARGV[0])))) . "\n";
More information about the ILUG
mailing list