——#!/usr/bin/perl
=encoding utf8
=begin metadata
Name: base64
Description: encode and decode base64 data
Author: Michael Mikonos
License: artistic2
=end metadata
=cut
use
strict;
use
warnings;
my
$VERSION
=
'1.0'
;
my
$Program
= basename($0);
my
(
%opt
,
$bufsz
,
$in
,
$out
);
getopts(
'do:v'
, \
%opt
) or usage();
if
(
scalar
(
@ARGV
) > 1) {
warn
"$Program: too many arguments\n"
;
usage();
}
if
(
$opt
{
'v'
}) {
"$Program version $VERSION\n"
;
exit
EX_SUCCESS;
}
$bufsz
=
$opt
{
'd'
} ? 76 : 57;
$bufsz
*= 20;
if
(
defined
$opt
{
'o'
}) {
unless
(
open
$out
,
'>'
,
$opt
{
'o'
}) {
warn
"$Program: cannot open '$opt{o}': $!\n"
;
exit
EX_FAILURE;
}
}
else
{
$out
=
*STDOUT
;
}
if
(
defined
$ARGV
[0] &&
$ARGV
[0] ne
'-'
) {
if
(-d
$ARGV
[0]) {
warn
"$Program: '$ARGV[0]' is a directory\n"
;
exit
EX_FAILURE;
}
unless
(
open
$in
,
'<'
,
$ARGV
[0]) {
warn
"$Program: cannot open '$ARGV[0]': $!\n"
;
exit
EX_FAILURE;
}
}
else
{
$in
=
*STDIN
;
}
$opt
{
'd'
} ? decode() : encode();
unless
(
close
$in
) {
warn
"$Program: failed to close input: $!\n"
;
exit
EX_FAILURE;
}
unless
(
close
$out
) {
warn
"$Program: failed to close output: $!\n"
;
exit
EX_FAILURE;
}
exit
EX_SUCCESS;
sub
decode {
my
$buf
=
''
;
while
(
readline
$in
) {
s/\s//g;
if
(m/[^A-Za-z0-9\+\/\=]/) {
warn
"$Program: bad input\n"
;
exit
EX_FAILURE;
}
$buf
.=
$_
;
if
(
length
(
$buf
) >=
$bufsz
) {
my
$chunk
=
substr
(
$buf
, 0,
$bufsz
);
{
$out
} decode_base64(
$chunk
);
$buf
=
substr
(
$buf
,
$bufsz
);
}
}
if
(
length
$buf
) {
{
$out
} decode_base64(
$buf
);
# end chunk
}
}
sub
encode {
my
$buf
;
while
(
read
$in
,
$buf
,
$bufsz
) {
{
$out
} encode_base64(
$buf
);
}
}
sub
usage {
warn
"usage: $Program [-dv] [-o FILE] [FILE]\n"
;
exit
EX_FAILURE;
}
__END__
=pod
=head1 NAME
base64 - encode and decode base64 data
=head1 SYNOPSIS
base64 [-dv] [-o FILE] [FILE]
=head1 DESCRIPTION
When encoding (the default mode), a binary file
is read and a base64 format file is created.
If no input file argument is provided, or file is '-',
stdin will be used.
The base64 output contains 76 characters per line.
Output is written to stdout by default.
When decoding, the input file is expected to contain
only valid base64 characters (alphanumeric, '+', '/' and '=').
Spaces are ignored when decoding. Selecting a binary file
as input will result in an error.
=head2 OPTIONS
The following options are available:
=over 4
=item -d
Decode data
=item -o FILE
Write output to the specified FILE
=item -v
Print version number and exit
=back
=head1 BUGS
No option exists for wrapping encoded base64 output at different
column widths.
It might be desirable to ignore unrecognised input characters when
decoding. This version of base64 has no option for relaxing the
input validation.
=head1 AUTHOR
Written by Michael Mikonos.
=head1 COPYRIGHT
Copyright (c) 2023 Michael Mikonos.
This code is licensed under the Artistic License 2.