#!/usr/local/bin/perl -w

# Written by Ben Reser <echelon@reser.org>
# This software is in the public domain, no warranties, representations are made.
# USE AT YOUR OWN RISK!

use strict;
use MIME::Base64;

my $input = '';
while (<>) {
  if (!defined($input)) {
    $input = $_;
  } else {
    $input .= $_;
  }
}
my (@mapping) = <DATA>;
chomp @mapping;
my (%mapping) = ();
for (my $i = 0; $i <= $#mapping; $i++) {
  $mapping{$mapping[$i]} = $i;
}

if ($input =~ /\-{5}BEGIN ECHELON ARMOR BLOCK\-{5}(?:.*?)(?:\n\n|\r\n\r\n)(.*?)\-{5}END ECHELON ARMOR BLOCK\-{5}/s) {
  my ($armor_block) = $1;
  print echelonarmordecode($armor_block);
} else {
  print echelonarmorencode($input);
}

sub echelonarmorencode {
  my $plain_text = shift;

  my $step1 = MIME::Base64::encode($plain_text,'');
  my (@step1) = split //,$step1;
  my (@step2) = ();
  foreach my $char (@step1) {
    push @step2, b642ea($char);    
  }
  my ($step3) = "-----BEGIN ECHELON ARMOR BLOCK-----\nVersion: Echelon Armor 1.0 http://ben.reser.org/echelon/\n\n";
  my ($current_line_count) = 0;
  foreach my $entry (@step2) {
    $current_line_count += length($entry) + 2;
    if ($current_line_count > 65) {
      $current_line_count = 0;
      $step3 .= "\n";
    }
    $step3 .= $entry . '  ';
  }
  $step3 .= "\n-----END ECHELON ARMOR BLOCK-----\n";
  return $step3;
}

sub echelonarmordecode {
  my $cipher_text = shift;

  my (@step1) = split /  |\n|\r\n/, $cipher_text;
  my ($step2) = '';
  foreach my $entry (@step1) {
    if ($entry =~ /^$/) {
      next;
    }
    if (!defined($step2)) {
      $step2 = ea2b64($entry);
    } else {
      $step2 .= ea2b64($entry);
    }
  }  
  return MIME::Base64::decode($step2);
}

sub b642ea {
  my $char = shift;

  my $ord = ord($char);
  if ($ord >= 65 && $ord <= 90) {
    $ord -= 65; # returns 0 - 25
  } elsif ($ord >= 97 && $ord <= 122) {
    $ord -= 71; # returns 26 - 51
  } elsif ($ord >= 48 && $ord <= 57) {
    $ord += 4; # returns 52 - 61
  } elsif ($ord == 43) {
    $ord = 62; # returns 62
  } elsif ($ord == 47) {
    $ord = 63; # returns 63;
  } elsif ($ord == 61) { 
    $ord = 64; # returns 64
  } 
  return $mapping[$ord];
}

sub ea2b64 {
  my $entry = shift;
  
  my $ord = $mapping{$entry};
  if ($ord >= 0 && $ord <= 25) {
    $ord += 65;
  } elsif ($ord >= 26 && $ord <= 51) {
    $ord += 71;
  } elsif ($ord >= 52 && $ord <= 61) {
    $ord -= 4;
  } elsif ($ord == 62) {
    $ord = 43;
  } elsif ($ord == 63) {
    $ord = 47;
  } elsif ($ord == 64) {
    $ord = 61;
  }
  return chr($ord);
}

__DATA__
FBI
CIA
NSA
IRS
ATF
BATF
DOD
WACO
RUBY RIDGE
OKC
OKLAHOMA CITY
MLITIA
GUN
HANDGUN
MILGOV
ASSAULT RIFLE
TERRORISM
BOMB
DRUG
HORIUCHI
KORESH
DAVIDIAN
KAHL
POSSE
COMITATUS
RANDY WEAVER
VICKIE WEAVER
SPECIAL FORCES
LINDA THOMPSON
SPECIAL OPERATIONS GROUP
SOG
SOF
DELTA FORCE
CONSTITUTION
BILL OF RIGHTS
WHITEWATER
POM
PARK ON METER
ARKANSIDE
IRAN CONTRAS
OLIVER NORTH
VINCE FOSTER
PROMIS
MOSSAD
NASA
MI5
ONI
CID
AK47
M16
C4
MALCOLM X
REVOLUTION
CHEROKEE
HILLARY
BILL CLINTON
GORE
GEORGE BUSH
WACKENHUT
TERRORIST
TASK FORCE 160
SPECIAL OPS
12TH GROUP
5TH GROUP
SF
