import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.math.*;
class desifrator{
final static String confPath = "conf.txt";
static char[] freq = new char[26];
static char[] abc = new char[26];
static String A = "";
static String B = "";
static String cestaA = " ";
static String cestaB = " ";
static Scanner freqSada = new Scanner(System.in);
static Scanner slovnik = new Scanner(System.in);
static Scanner delkaSlov = new Scanner(System.in);
static Scanner presnostSlov = new Scanner(System.in);
static Scanner slovnikAuto = new Scanner(System.in);
static String volbaSady = "cze1";
static String volbaSlovniku = "ne";
static int delka = 4;
static double presnost = 0.75;
static String auto = "ne";
static String pred = " ";
static String bude = " ";
public static void otevriSoubory(){
Scanner confFile;
File conf = new File(confPath);
if(conf.exists()){
System.out.println("... konfiguracni soubor cest nalezen" + "\t \"" + confPath + "\"");
try{
confFile = new Scanner(new File(confPath));
cestaA = confFile.next();
cestaB = confFile.next();
}catch(Exception e){
System.out.println("FAIL");
}
}else{
System.out.println("... nenalezen konfiguracni soubor cest !");
System.exit(0);
}
File ciphertext = new File(cestaA);
File slovnik = new File(cestaB);
if(ciphertext.exists()){
System.out.println("... text pro analyzu nalezen" + "\t\t \"" + cestaA + "\"");
}else{
System.out.println("... nenalezen soubor pro analyzu !");
System.exit(0);
}
if(slovnik.exists()){
System.out.println("... slovnik pro analyzu nalezen" + "\t\t \"" + cestaB + "\"");
}else{
System.out.println("... slovnik pro analyzu nenalezen !");
System.exit(0);
}
}
public static void frekvencniAnalyza(){
int freqPos = 0;
String cele = "";
String text = "";
Scanner soubor;
Map hm = new HashMap();
int pomocna = 0;
int max = 0;
int maxChar = 0;
try{
soubor = new Scanner(new File(cestaA));
while(soubor.hasNext()){
cele = cele + soubor.next();
cele = cele.toLowerCase();
}
soubor.close();
}catch(Exception e){
System.out.println("FAIL");
}
try{
soubor = new Scanner(new File(cestaA));
while(soubor.hasNext()){
text = text + soubor.next() + " ";
}
soubor.close();
}catch(Exception e){
System.out.println("FAIL");
}
//System.out.println(cele);
System.out.println("--------------------------------------------------------------------------------");
System.out.println("Frekvencni analyza na zaklade cestnosti znaku pro cesky jazyk se sadou " + "\"" + volbaSady + "\":");
System.out.println();
System.out.println(text);
System.out.println();
A = text;
for(int i = 0; i < cele.length(); i++){
if(hm.containsKey(cele.charAt(i))){
pomocna = (Integer) hm.get(cele.charAt(i));
hm.put(cele.charAt(i), pomocna + 1);
}else{
hm.put(cele.charAt(i),1);
}
}
while(hm.size() != 0){
for(int i = 97; i < 123; i++){
if(hm.get((char)i) != null){
pomocna = (Integer) hm.get((char)i);
if(pomocna > max){
max = pomocna;
maxChar = i;
}
}
}
abc[freqPos]=(Character.toUpperCase((char)maxChar));
text=text.replace(Character.toUpperCase(((char)maxChar)),freq[freqPos]);
max = 0;
freqPos++;
hm.remove((char)maxChar);
}
System.out.println(text);
B = text;
System.out.println();
vypisTabulky();
System.out.println("--------------------------------------------------------------------------------");
System.out.println();
}
public static void vypisTabulky(){
System.out.print("| ");
for(int i=0; i <= 25; i++){
System.out.print(Character.toUpperCase(abc[i]) + " ");
}
System.out.println();
System.out.print("| ");
for(int i=0; i <= 25; i++){
System.out.print((freq[i]) + " ");
}
System.out.println();
}
public static void zmenText(){
B = A;
for(int i = 0; i <= 25; i++){
B = B.replace(abc[i],freq[i]);
}
}
public static void vypisTexty(){
System.out.println(A);
System.out.println(B);
}
public static void vypisText(){
System.out.println(B);
System.out.println("--------------------------------------------------------------------------------");
}
public static void zamenPismena(char a, char b){
int poziceA = 0;
int poziceB = 0;
for(int i = 0; i <= 25; i++){
if((int)freq[i] == (int)a){
poziceA = i;
}
}
for(int i = 0; i <= 25; i++){
if((int)freq[i] == (int)b){
poziceB = i;
}
}
freq[poziceA]=b;
freq[poziceB]=a;
}
public static void slovnik(){ try {
Scanner soubor;
HashMap<String, Integer> cm = new HashMap<String, Integer>();
int pomocna = 0;
int hledane = 0;
int nalezene = 0;
double usp = 0;
int navrhSum = 0;
String navrhStr = "";
char z = ' ';
char na = ' ';
System.out.println("Provadim prohledavani slovniku a parovani slov dle zadanych parametru.");
ArrayList<String> slova = new ArrayList<String>();
Scanner tokenize = new Scanner(B);
while (tokenize.hasNext()) {
slova.add(tokenize.next());
}
for(int i=0; i < slova.size(); i++){
String s = (String)slova.get(i);
int sl = s.length();
int match = 0;
String nejlepsi = "";
double predchozi = 0;
if(sl >= delka){
hledane++;
try{
BufferedReader slovnik = new BufferedReader(new InputStreamReader(new DataInputStream(new FileInputStream("cze.txt"))));
String word;
while((word = slovnik.readLine()) != null){
if(word.length() == sl){
for(int y=0; y < sl; y++){
if((int)(s.charAt(y)) == (int)(word.charAt(y))){
match++;
}
}
double pomer = ((double)(match) / (double)(sl));
if(pomer >= presnost){
if(pomer > predchozi){
nejlepsi = word;
predchozi = pomer;
}
}
match=0;
pomer=0;
}
}
//System.out.println(nejlepsi);
System.out.print(".");
if(nejlepsi != ""){
usp = usp + predchozi;
nalezene++;
for(int y=0; y < sl; y++){
if((int)(s.charAt(y)) != (int)(nejlepsi.charAt(y))){
String zmena = Character.toString((s.charAt(y))) + Character.toString((nejlepsi.charAt(y)));
if(cm.containsKey(zmena)){
pomocna = (Integer) cm.get(zmena);
cm.put(zmena, pomocna + 1);
}else{
cm.put(zmena,1);
}
}
}
}
}catch(Exception e){
System.out.println("FAIL");
}
}
}
for(Map.Entry<String, Integer> e : cm.entrySet()){
//System.out.println(e.getKey() + " " + e.getValue());
if(e.getValue() > navrhSum){
navrhStr = e.getKey();
navrhSum = e.getValue();
}
}
na = navrhStr.charAt(1);
z = navrhStr.charAt(0);
usp = usp / nalezene;
System.out.println();
System.out.println();
bude = z + "" + na;
double uspUpr = usp * 100;
System.out.println("Pocet uspesne sparovanych slov:\t\t " + nalezene + " z " + hledane);
System.out.printf("Prumerna presnost rozpoznani slov:\t %.1f", uspUpr); System.out.print(" %");System.out.println();
if(auto.equalsIgnoreCase("ne")){
if((navrhSum >= 3) && (((double)nalezene/(double)hledane) > 0.4) && (usp < 0.99)){
System.out.println("Rada slovniku pro dalsi zmenu:\t\t " + z + " -> " + na);
}else{
System.out.println("Rada slovniku pro dalsi zmenu:\t\t " + "... slovnik neni schopen poradit");
}
manual();
}else{
if((((double)nalezene/(double)hledane) > 0.5) && (usp < 0.99) && (usp > 0.80) && (navrhSum > 4) && (!bude.equals(pred))){
System.out.println("Automaticky provadim zmenu znaku:\t " + z + " -> " + na);
System.out.println();
pred = z + "" + na;
zamenPismena(Character.toLowerCase(z),Character.toLowerCase(na));
vypisTabulky();
zmenText();
System.out.println();
vypisText();
slovnik();
}else{
if(bude.equals(pred)){
zamenPismena(Character.toLowerCase(na),Character.toLowerCase(z));
zmenText();
System.out.println("!!! Riziko zacykleni neprovadim zmenu " + z + " -> " + na + " !!!");
System.out.println();
vypisText();
}else{
if((navrhSum >= 3) && (((double)nalezene/(double)hledane) > 0.4) && (usp < 0.99)){
System.out.println("Rada slovniku pro dalsi zmenu:\t\t " + z + " -> " + na);
}else{
System.out.println("Rada slovniku pro dalsi zmenu:\t\t " + "... slovnik neni schopen poradit");
}
}
manual();
}
} } catch (Exception e) { }
}
public static void manual(){
System.out.println();
Scanner vstupA = new Scanner(System.in);
Scanner vstupB = new Scanner(System.in);
String A;
String B;
System.out.print("Zadejte pismeno, ktere si prejete zmenit:\t");
A = vstupA.nextLine();
System.out.print("Zadejte pismeno, ktere za nej chcete dosadit:\t");
B = vstupB.nextLine();
System.out.println();
zamenPismena(Character.toLowerCase(A.charAt(0)),Character.toLowerCase(B.charAt(0)));
vypisTabulky();
zmenText();
System.out.println();
vypisText();
if(volbaSlovniku.equalsIgnoreCase("ano")){
slovnik();
}
manual();
}
public static void menu(){
System.out.println("********************************************************************************");
System.out.println(" Vitejte v programu pro kryptoanalyzu monoalfabeticke substitucni sifry ");
System.out.println("********************************************************************************");
otevriSoubory();
System.out.println("--------------------------------------------------------------------------------");
System.out.print("Zvolte sadu cestnosti znaku daneho jazyka (cze0,cze1):\t ");
volbaSady = freqSada.nextLine();
if(volbaSady.equalsIgnoreCase("cze0")){
char [] freqCh = {'e','a','o','i','n','s','t','r','v','u','l','z','d','k','p','m','c','y','h','j','b','g','f','x','w','q'};
freq = freqCh;
}else{
char [] freqCh = {'e','t','o','a','n','i','r','s','h','d','l','c','f','u','m','p','y','w','g','b','v','k','j','z','q','x'};
freq = freqCh;
}
System.out.print("Prejete si vyuzit slovnik ? (ano/ne):\t\t\t ");
volbaSlovniku = slovnik.nextLine();
if(volbaSlovniku.equalsIgnoreCase("ne")){
frekvencniAnalyza();
manual();
}else{
System.out.print("Jaka je minimalni delka slov pro porovnavani ? (3-9):\t ");
delka = delkaSlov.nextInt();
System.out.print("Jakou min. presnost u slov zvolite ? (napr. 0,80 = 80%): ");
presnost = presnostSlov.nextDouble();
System.out.print("Moznost automatickych zmen dle slozniku ? (ano/ne):\t ");
auto = slovnikAuto.nextLine();
frekvencniAnalyza();
slovnik();
}
}
}
public class kas {
public static void main(String[] args) {
desifrator novy = new desifrator();
novy.menu();
}
}