#!/usr/bin/perl -w
################################################################
# coladj.pl                                                    #
#   Test version                                               #
#--------------------------------------------------------------#
# Take a disk ciphertext of assumed period $ll and test the    #
#   $ll$ columns against each other -- for each pair of        #
#   columns find the optimal relative alphabet shift.          #
#--------------------------------------------------------------#
# Input from command line : assumed period $ll                 #
# Input from STDIN : ciphertext                                #
# Output to STDOUT : the optimal shift values.                 #
#--------------------------------------------------------------#
# Transliteration of special characters according to English   #
#   rules                                                      #
# For special characters of other languages use preptext.pl    #
#   first.                                                     #
#--------------------------------------------------------------#
# Klaus Pommerening 2014-Jan-05                                #
#                                                              #
# This program is freeware. Use it as you like.                #
# Usual disclaimers apply.                                     #
################################################################

require "auxcrypt.pl";  # Use procedures &gettext, &chi.
$ll = $ARGV[0];
$ciphertext = &gettext;
$rr = length($ciphertext);
# print $ciphertext, "\n";
print "Length of ciphertext: ", $rr, " | Assumed period: ", $ll, "\n";

@textlist = split(//,$ciphertext); # Split into single letters.

@parttext = ();                 # Initialize list @parttext
#  @phivalues = ();                # Initialize list of @phivalues

# ---------- Pick $ll partial texts
for ($i = 0; $i < $rr; $i++) {         # Loop through @textlist
  $parttext[$i % $ll] .= $textlist[$i]; # and append the $i-th letter
                                       # to parttext[$i mod $ll].
  } #--- for $i --------------------------------------
for ($j = 0; $j < $ll; $j++) {
  print "Part ", $j, " of length ", length($parttext[$j]), " is ", $parttext[$j], "\n";
  }
for ($j = 0; $j < $ll; $j++) {
  for ($k = $j+1; $k < $ll; $k++) {
    print "Part ", $k, " versus part ", $j, " has optimal relative shift of ";
    print &optshift($parttext[$j],$parttext[$k]), "\n";
    }
  } #--- for $j --------------------------------------

################################################################
# Subroutine optshift                                          #
#   Input: two strings $_0 and $_1 in A..Z                     #
#   Output: The alphabet shift of $_1 that maximizes the chi   #
#     (cross-product sum) of $_0 and shifted($_1).             #
################################################################
sub optshift {
  my $text0 = $_[0];
  my $text1 = $_[1];
  my @chilist = ();
  my $chivalue;
  my $i;
  my $shift = 0;                        # Initialize.
  while ($shift < 26) {                 # Loop over $shift.
    $chivalue = &chi($text0,$text1); # Cross-product sum
    push @chilist, $chivalue;
    $text1 =~ tr/A-Z/B-ZA/;
    $shift++;
    } #--- while -----
  my $max = 0;
  my $idx = 0;
  for ($i = 0; $i < 26; $i++) {
    if ($chilist[$i] > $max) {
      $max = $chilist[$i];
      $idx = $i;
      } #--- if -----
    } #--- for $i -----
  return $idx;
}