#!/usr/bin/perl

use strict;
use warnings;

our %freq_hrv = (
    a=>0.115, b=>0.015, c=>0.028, d=>0.037, e=>0.084, f=>0.003, g=>0.016,
    h=>0.008, i=>0.098, j=>0.051, k=>0.036, l=>0.033, m=>0.031, n=>0.066,
    o=>0.090, p=>0.029, q=>0.000, r=>0.054, s=>0.056, t=>0.048,
    u=>0.043, v=>0.035, w=>0.000, x=>0.000, y=>0.000, z=>0.023
);

sub read_file {
    undef $/; # Zelim ucitati citav fajl odjednom, a ne red po red.
    open FILE, shift;
    my $line = lc <FILE>; # Ucitam i odmah bacim u lowercase.
    $line=~s/\s//g; # Brisem praznine.
    our @sifrat = split '', $line; # Splitam u polje slova.
}

sub duljina_kljuca {
    # Nakon sto za odredjenu duljinu kljuca $m seciram @sifrat na $m
    # podnizova, analizu slova podnizova pohranjujem u $m hash tablica
    # oblika (slovo => frekvencija).
    # Polje s referencama na te hash tablice pridruzujem kljucu $m
    # u globalnoj hash tablici %analiza.
    our @sifrat;
    our %analiza;

    for (my $m=3; $m<=15; $m++) {
	$analiza{$m}=[]; # Pridruzim $m => referenca na prazano polje.
	print "m=$m: ";
	for (my $pocetak=0; $pocetak<$m; $pocetak++) { # Seciram @sifrat.
	    my %hash=(); # Inicijaliziram prazan %hash za analizu slova,
	    my ($ic, $n)=(0.0, 0); # indeks koincidencije i $n.
	    for (my $i=$pocetak; $sifrat[$i]; $i+=$m, $n++) {
		$hash{$sifrat[$i]}++; # Znaku $sifrat[$i] uvecam frekvenciju.
	    }
	    push @{$analiza{$m}}, \%hash; # Dodajem referencu \%hash.
	    foreach (keys %hash) { # Racunam $ic.
		$ic+=$hash{$_}*($hash{$_}-1);
	    }
	    $ic/=$n*($n-1);
	    printf " %.3f", $ic;
	}
	print "\n";
    }
}

sub obradi_duljinu {
    our %analiza;
    my %indices;

    # Ucitavam duljinu kljuca sa STDIN-a.
    print "\nm=";
    my $m=<STDIN>;
    chomp $m;

    # $aref su reference na hasheve s analizama slova.
    foreach my $aref (@{$analiza{$m}}) {
	for (my $pomak=0; $pomak<26; $pomak++) {
	    my ($mic, $n)=(0.0, 0);
	    foreach my $key (keys %$aref) {
		# $slovo je $key pomaknut za $pomak.
		my $slovo=chr((ord($key)-ord('a')-$pomak)%26+ord('a'));
		$mic+=$freq_hrv{$slovo}*$aref->{$key}; # Racunam $mic.
		$n+=$aref->{$key};
	    }
	    $mic/=$n;
	    # U hash tablicu %indices svakom pomaku (sada slovu)
	    # pridruzujem medjusobni indeks koincidencije.
	    $indices{chr($pomak+ord('a'))}=$mic;
	}
	# Ispisujem indekse sortirane silazno
	foreach my $key (sort {$indices{$b}<=>$indices{$a}} keys %indices) {
	    last if ($indices{$key}<0.05);
	    printf " %s-%.3f", $key, $indices{$key};
	}
	print "\n";
    }
}

sub desifriraj {
    our @sifrat;

    print "\nUnesi kljuc: ";
    my $input=<STDIN>;
    chomp $input;
    my @kljuc=split '', $input;
    my $slovo;

    foreach (@sifrat) {
	$slovo=chr((ord($_)-ord($kljuc[0]))%26+ord('a'));
	print $slovo;
	push @kljuc, shift @kljuc;
    }
    print "\n";
}

my $input = $/;
read_file @ARGV;
duljina_kljuca;
$/=$input;
obradi_duljinu;
desifriraj;
