onlyf onlyf - 2 years ago 160
Perl Question

Perl - Encoding to and from base64

i ve written the following script to convert files from and to base64.

# Setup default mode
my $mode = '';
my $encoding = 'base64';
my $file = '';

'mode=s' => \$mode, # mode = Encode / decode
'help!' => \$help, # help message
'encoding=s' => \$encoding,
'file=s' => \$file
) or die "Incorrect usage!\n";

if( $help ) {
print "Common on, it's really not that hard.\n";
} else {
print "# Script parameters provided : \n";
print "# Mode set to $mode.\n";
print "# Encoding is set to $encoding\n";
print "# Input File set to $file \n";

open(FILE, "$file") or die "$!";
open FILEOT, ">$file.out" or die "$!";
binmode FILEOT;
binmode STDOUT;

switch ($mode) {

case "encode" {

print "# Encoding file $file to $encoding \n";
print "# Processing .... \n\n";

while (read(FILE, $buf, 60*57)) {
$encoded = encode_base64($buf);
print $encoded;
print FILEOT $encoded;

case "decode" {
print "# Decoding file $file from $encoding \n";
print "# Processing .... \n\n";

while ( read(FILE, $buf, 60*57 ) {
$decoded = decode_base64($buf);
print $decoded;
print FILEOT $decoded;

The encoding part works as intended. The decoding part does not give any output. I gave it an input file of the likes :

My name is John
I eat pineapples

and it gives no output. I think the buffered read may not be required in the case of decoding a file already encoded with this script earlier. I used the above test to produce the base64 encoding version but the reverse gives nothing. Can anyone help me?

Answer Source

The block-wise encode/decode won't work. The encoding will result in a bigger output than necessary, because you restart every 60 * 57 = 3420 bytes, but for decoding, 3420 bytes won't be a complete Base64 block. Look at your result, you'll probably see not completely filled lines ending with some = chars.

Here is a short sample with a blocksize of 10 for demonstration:

use MIME::Base64 qw(encode_base64);

my $in = "abcdefghijklmnopqrstuvwxyz";
while (my $block = substr($in,0,10,"")) {
    print encode_base64($block);


Trying to decode this in blocks of 10 chars will try to decode these strings:


The first line correctly translates to abcdefg, but the second line is decoded to garbage.

There's a command line tool called base64 which does excatly the same: Encode and decode Base64 files. You should remove that blockwise processing, encode a file and try to decode it using the command line tool (assuming that it does things right). If this is working, your encode is also working, otherwise your encode doesn't work probably. Make it working and continue to the decoding part.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download