1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
# $Id: base64.pl,v 2.5 2011/01/02 06:50:26 ehood Exp $
#
# Library based on Perl 4 code from:
# base64.pl -- A perl package to handle MIME-style BASE64 encoding
# A. P. Barrett <barrett@ee.und.ac.za>, October 1993
# Revision: 1.4 Date: 1994/08/11 16:08:51
#
# Subsequent changes made by Earl Hood, earl@earlhood.com.
package base64;
my $_have_MIME_Base64;
BEGIN {
eval { require MIME::Base64; };
$_have_MIME_Base64 = scalar($@) ? 0 : 1;
}
# Synopsis:
# require 'base64.pl';
#
# $uuencode_string = &base64::b64touu($base64_string);
# $binary_string = &base64::b64decode($base64_string);
# $base64_string = &base64::uutob64($uuencode_string);
# $base64_string = &base64::b64encode($binary_string);
# $uuencode_string = &base64::uuencode($binary_string);
# $binary_string = &base64::uudecode($uuencode_string);
#
# uuencode and base64 input strings may contain multiple lines,
# but may not contain any headers or trailers. (For uuencode,
# remove the begin and end lines, and for base64, remove the MIME
# headers and boundaries.)
#
# uuencode and base64 output strings will be contain multiple
# lines if appropriate, but will not contain any headers or
# trailers. (For uuencode, add the "begin" line and the
# " \nend\n" afterwards, and for base64, add any MIME stuff
# afterwards.)
####################
my $base64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
'abcdefghijklmnopqrstuvwxyz'.
'0123456789+/';
my $base64_pad = '=';
my $uuencode_alphabet = q|`!"#$%&'()*+,-./0123456789:;<=>?|.
'@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
my $uuencode_pad = '`';
# Build some strings for use in tr/// commands.
# Some uuencodes use " " and some use "`", so we handle both.
# We also need to protect backslashes and other special characters.
my $tr_uuencode = " ".$uuencode_alphabet;
$tr_uuencode =~ s/(\W)/\\$1/g;
my $tr_base64 = "A".$base64_alphabet;
$tr_base64 =~ s/(\W)/\\$1/g;
sub b64touu
{
local ($_) = shift;
my ($result);
# zap bad characters and translate others to uuencode alphabet
eval qq{
tr|$tr_base64||cd;
tr|$tr_base64|$tr_uuencode|;
};
# break into lines of 60 encoded chars, prepending "M" for uuencode
while (s/^(.{60})//) {
$result .= 'M' . $1 . "\n";
}
# any leftover chars go onto a shorter line
# with padding to the next multiple of 4 chars
if ($_ ne '') {
$result .= substr($uuencode_alphabet, length($_)*3/4, 1)
. $_
. ($uuencode_pad x ((60 - length($_)) % 4)) . "\n";
}
# return result
$result;
}
sub b64decode
{
# call more efficient module if available (ehood, 2003-09-28)
if ($_have_MIME_Base64) {
return &MIME::Base64::decode_base64;
}
# substr() usage added by ehood, 1996/04/16
local($str) = shift;
my($result, $tmp, $offset, $len);
# zap bad characters and translate others to uuencode alphabet
eval qq{
\$str =~ tr|$tr_base64||cd;
\$str =~ tr|$tr_base64|$tr_uuencode|;
};
# break into lines of 60 encoded chars, prepending "M" for uuencode,
# and then using perl's builtin uudecoder to convert to binary.
$result = ''; # init return string
$offset = 0; # init offset to 0
$len = length($str); # store length
while ($offset+60 <= $len) { # loop until < 60 chars left
$tmp = substr($str, $offset, 60); # grap 60 char block
$offset += 60; # increment offset
$result .= unpack('u', 'M' . $tmp); # decode block
}
# also decode any leftover chars
if ($offset < $len) {
$tmp = substr($str, $offset, $len-$offset);
$result .= unpack('u',
substr($uuencode_alphabet, length($tmp)*3/4, 1) . $tmp);
}
# return result
$result;
}
sub uutob64
{
# This is the most difficult, because some perverse uuencoder
# might have made lines that do not describe multiples of 3 bytes.
# I don't see any better method than uudecoding to binary and then
# b64encoding the binary.
&b64encode(&uudecode); # implicitly pass @_ to &uudecode
}
sub b64encode
{
# call more efficient module if available (ehood, 2003-09-28)
if ($_have_MIME_Base64) {
return &MIME::Base64::encode_base64;
}
local ($_) = shift;
my ($chunk);
my ($result);
# break into chunks of 45 input chars, use perl's builtin
# uuencoder to convert each chunk to uuencode format,
# then kill the leading "M", translate to the base64 alphabet,
# and finally append a newline.
while (s/^([\s\S]{45})//) {
$chunk = substr(pack('u', $1), $[+1, 60);
eval qq{
\$chunk =~ tr|$tr_uuencode|$tr_base64|;
};
$result .= $chunk . "\n";
}
# any leftover chars go onto a shorter line
# with uuencode padding converted to base64 padding
if ($_ ne '') {
$chunk = substr(pack('u', $_), $[+1,
int((length($_)+2)/3)*4 - (45-length($_))%3);
eval qq{
\$chunk =~ tr|$tr_uuencode|$tr_base64|;
};
$result .= $chunk . ($base64_pad x ((60 - length($chunk)) % 4)) . "\n";
}
# return result
$result;
}
sub uuencode
{
local ($_) = shift;
my ($result);
# break into chunks of 45 input chars, and use perl's builtin
# uuencoder to convert each chunk to uuencode format.
# (newline is added by builtin uuencoder.)
while (s/^([\s\S]{45})//) {
$result .= pack('u', $1);
}
# any leftover chars go onto a shorter line
# with padding to the next multiple of 4 chars
if ($_ ne '') {
$result .= pack('u', $_);
}
# return result
$result;
}
sub uudecode
{
local ($_) = shift;
my $result = '';
# strip out begin/end lines (ehood, 1996/03/21)
s/^\s*begin[^\n]+\n//;
s/\nend\s*$//;
# use perl's builtin uudecoder to convert each line
while (s/^([^\n]+\n?)//) {
last if substr($1, 0, 1) eq '`';
$result .= unpack('u', $1);
}
# return result
$result;
}
1;
|