################################################################
# portadec.pl : Porta-Belaso cipher over the alphabet [A..Z]   #
#    - decryption -                                            #
#    Input from STDIN : ciphertext                             #
#    Output to STDOUT : plaintext                              #
#    Keys from command line :                                  #
#      key[0] determines the base alphabet.                    #
#             Example: key[0] = "SECRET" gives                 #
#                               SECRTABDFGHIJKLMNOPQUVWXYZ     #
#      key[1] determines which shift of the base alphabet to   #
#             use for each single position in the plain text.  #
#--------------------------------------------------------------#
# Klaus Pommerening 7. Juni 1997, 30. April 2002               #
#                                                              #
# This program is freeware. Use it as you like.                #
# Usual disclaimers apply.                                     #
################################################################

require "auxcrypt.pl";

$key[0] = $ARGV[0];                 # Get keys from command line.
$key[1] = $ARGV[1];                 #
$permut = &makeperm($key[0]);       # Make permutation from key.
$_ = &to26($key[1]);                # Prepare for using eval with tr
eval "tr/$permut/A-Z/";             # Preprocess key for addtext
$runkey = $_;

$_ = &gettext;                      # Get plaintext from standard
                                    #   input.
eval "tr /$permut/A-Z/";            # 1st step: monoalph. decr.
$plaintext = $_;
$_ = &subtext($plaintext);          # 2nd step: running-key

&puttext($_);                       # Output plaintext.

################################################################
# Subroutine subtext                                           #
#   Running text cipher                                        #
#     We identify the alphabet A-Z with the integers           #
#     0..25 and subtract the runkey from the ciphertext mod 26 #
#     to get the plaintext elementwise. If the runkey is       #
#     exhausted before the ciphertext, it is repeated from its #
#     beginning.                                               #
#   Input:  ciphertext as string of uppercase characters       #
#   Output: plaintext as string of uppercase characters        #
#   Global variable: $runkey                                   #
################################################################
sub subtext {
  local(@inlist) = split(//,$_[0]);# Get input
  local(@key) = split(//,$runkey);# Runkey as list
  local($plain);                  # Plaintext for output
  local($i);                      # Loop counter
  local($j) = 0;                  # Auxiliary counter
  local($x);                      # Auxiliary variable
  local($y);                      # Auxiliary variable
  local($z);                      # Auxiliary variable

  for ($i = 0; $i < @inlist; $i++) {
    $x = $sa{$inlist[$i]};        # Interpret letter as number
    $y = $sa{$key[$j]};
    $z = $x - $y;                 # Running text cipher
    if ($z < 0) {$z = $z + 26;}
    $plain .= $alphabet[$z];      # Append cipher text letter
    $j++;
    if ($j == @key) {$j = 0;}     # Da capo
    }
  return $plain;
  } #--- addtext -----------------------------------------------
