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:
[email protected] (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: <
[email protected]>
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:
[email protected]
#!/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
}