Article 6750 of comp.lang.perl: Xref: feenix.metronet.com comp.lang.perl:6750 Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!pipex!uunet!psgrain!ee.und.ac.za!tplinfm From: barrett@lucy.ee.und.ac.za (Alan Barrett) Newsgroups: comp.lang.perl Subject: MIME encoding/decoding in perl Date: 13 Oct 1993 15:46:46 +0200 Organization: Elec. Eng., Univ. Natal, Durban, S. Africa Lines: 63 Message-ID: <29h0s6$sgu@lucy.ee.und.ac.za> NNTP-Posting-Host: lucy.ee.und.ac.za Here's a base64 decoder. It uses pack/unpack with the 'B*' format to do much of the work. (Larry, any chance of direct support for the MIME base64 and quoted-printable encodings in pack/unpack? We have uuencode already...) --apb Alan Barrett, Dept. of Electronic Eng., Univ. of Natal, Durban, South Africa RFC822: barrett@ee.und.ac.za #!/usr/bin/perl # b64decode -- decode a raw BASE64 message # A P Barrett, October 1993 # usage: b64decode [files] # Input is read from stdin or from the named files. Each named file # is processed separately. The input should be raw base64-encoded data, # without any heades, trailers or other junk (so remove that first, # before using b64decode). See RFC-1341 for the definition of # base64 encoding. # Output is the decoded message, and is sent to stdout with 8 data bits # per output character. # The present implementation is horribly inefficient. $base64alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. 'abcdefghijklmnopqrstuvwxyz'. '0123456789+/'; # and '=' $base64pad = '='; $leftover = ''; while (<>) { # ignore illegal characters s/[^$base64alphabet]//go; # insert the leftover stuff from last time $_ = $leftover . $_; # if there are not a multiple of 4 bytes, keep the leftovers for later m/^((....)*)/; $_=$&; $leftover=$'; # turn each group of 4 values into 3 bytes s/(....)/&b64decodesub($1)/eg; # special processing at EOF for last few bytes if (eof) { $_ .= &b64decodesub($leftover); $leftover = ''; } # output it print $_; } # b64decodesub -- takes some characters in the base64 alphabet and # returns the raw bytes that they represent. sub b64decodesub { local ($_) = @_[0]; # translate each char to a value in the range 0 to 63 eval qq{ tr!$base64alphabet!\0-\77!; }; # keep 6 bits out of every 8, and pack them together $_ = unpack('B*', $_); # look at the bits s/(..)(......)/$2/g; # keep 6 bits of every 8 s/((........)*)(.*)/$1/; # throw away spare bits (not multiple of 8) $_ = pack('B*', $_); # turn the bits back into bytes $_; # return } .