package Acme::FASTA;
use strict;
our $class = __PACKAGE__;
our %dict = reverse( our %inv = map { ($_,sprintf "%02b",ord($_)>>1&3) } split //,'ACGT' );
sub encode($$) {
### Encode perl into FASTA - class name becomes FASTA header
local $_ = shift;
my $t = shift;
my $hash_bang = $t =~ /^(#\!.*)/m ? "$1\n\n" : "";
($t = $t =~ /package\s+(\S+)/ || /package\s+(\S+)/ ? "::$1" : '' ) =~s/;$//;
$_ = unpack "b*", $_;
s/(..)/$dict{$1}/g;
s/(.{60})/$1\n/g;
"${hash_bang}use $class;\n\n>$class$t\n$_\n";
}
sub decode($) {
### Decode FASTA back into perl
local $_ = shift;
s/.*^>$class//sm;
s/(.)/$inv{$1}/ges;
warn pack "b*", $_;
pack "b*", $_;
}
open 0 or print "Can't open '$0'\n" and exit;
($_ = join "", <0>) =~ s/(.*^\s*)use\s+$class;\n+//sm;
if( /^>$class/ ) {
do { eval decode $_; exit }
} else {
no strict 'refs';
open 0, ">$0" or print "Cannot encode '$0'\n" and exit;
print {0} encode $_,$1 and exit;
}
1;
__END__
=head1 NAME
Acme::FASTA - Genetic programming
=head1 SYNOPSIS
use Acme::FASTA;
print "Hello";
=head1 DESCRIPTION
Acme::FASTA obfuscates code by converting the script into a FASTA file.
The header of the FASTA file incorporates the package name in the module
if one is included.
This is inspired by Apache::DoubleHelix and Conway's Acme::Bleach.
The script also keeps intact the #! line so that you can still execute
the script with out having to "perl" it!
=head1 DIAGNOSTICS
=over 2
=item * Can't open '%s'
Acme::FASTA cannot access the source.
=item * Can't encode '%s'
Acme::FASTA cannot convert the source.
=back
=head1 AUTHOR
James Smith <js5@sanger.ac.uk>
=head1 LICENSE
Released under The Artistic License
=head1 SEE ALSO
L<Acme::Bleach>, L<Acme::Buffy>, L<Acme::Pony>
=cut