55d249a40db0f927c0a862e430e05b6ffac7dda6
[krypto.git] / krypto.py
1 #!/usr/bin/env python
2
3 """CL rozhrani pro sadu kryptoanalytickych nastroju."""
4
5 import sys
6 import pickle
7 import argparse
8
9 from ocesavac import ocesat
10 import jakobsen
11 from jakobsen import reference
12 import koincidence
13 import posuny
14 from spolecne import ABECEDA
15 import vigenere
16
17 opsny = ''
18
19 if opsny == 'H':
20     posli_mail(odesilatel, "Napoveda", ''.join("Napoveda:\n"
21                "Prikazy robotovi vkladejte do predmetu zpravy "
22                "zaslane na adresu ", 
23                settings.mail, ".\nNa velikosti pismen nezalezi."
24                "\n\nSeznam prikazu:\n"
25                "\"", settings.subject, "\"   Analyza zpravy z tela mailu.\n" 
26                "\"", settings.subject, " X\" Vynuti analyzu bez mezer.\n"
27                "\"", settings.subject, " M\" Vynuti analyzu s mezerami.\n"
28                "\"", settings.subject, " B\" Vypise cetnost vsech bigramu.\n"
29                "\"", settings.subject, " P\" Vypise vsechny posunuti textu.\n"
30                "\"", settings.subject, " A\" Vypise uplne vsechno co dava "
31                "alespon trochu smysl (nedoporucuji).\n"
32                "\"", settings.subject, " H\" Tato napoveda.\n"
33                "\nVolby (mimo \"H\") je mozno libovolne kombinovat.\n"
34                "Napriklad \"", settings.subject, " LXB\" analyzuje posledni "
35                "prijatou zpravu s vynucenim analyzy bez mezer a navic vypise "
36                "cetnosti bigramu.\n"
37                "\nS pozdravem\nVas Robot\n"))
38     sys.exit()
39
40 telo = sys.stdin.read()
41 zprava = telo.strip().upper()
42
43 # Prepinani spacemodu
44 mod_m = False
45 mod_x = False
46 if 'X' in opsny:
47     mod_x = True
48 if 'M' in opsny:
49     mod_m = True
50 if 'A' in opsny:
51     mod_x = True
52     mod_m = True
53 if not mod_m and not mod_x:
54     if ' ' in ocesat(zprava, True)[1:-1]:
55         mod_m = True
56         print "Automaticky zvolena analyza s mezerami."
57     else:
58         mod_x = True
59         print "Automaticky zvolena analyza bez mezer."
60     
61 # Zakladni udaje
62 print "\nZakladni udaje:"
63 if mod_m:
64     print ("Delka zpravy (vcetne mezer a zvlastnich znaku: " +
65         str(len(zprava)))
66 print ("Delka zpravy (bez mezer a zvlastnich znaku): " +
67     str(len(ocesat(zprava, False))))
68
69 # Prumerna delka slova
70 if mod_m:
71     print "\nPrumerna delka slova:"
72     slova = ocesat(zprava, True).split()
73     print ('{0:.3}'.format(float(sum([len(word) for word in slova]))/len(slova)))
74
75 # Frekvence znaku 
76 print "\nFrekvencni analyza:"
77 freq = dict()
78 for char in ABECEDA:
79     freq[char] = 0
80 for char in zprava:
81     if char in freq:
82         freq[char] += 1
83 celkem = sum(freq.values())
84 for char in sorted(freq, key=freq.get, reverse=True):
85     print ('{0} {1:>3} {2:>6.2%}'.format(char, freq[char],
86                    float(freq[char])/celkem))
87
88 # Index koincidence
89 if mod_m:
90     print "\nIndex koincidence (s mezerami):"
91     print ('{0:.2%}'.format(
92                    koincidence.index_koincidence(zprava, True)))
93 if mod_x and len(zprava) >= 30:
94     #TODO tady by se spravne mela porovnavat delka ocesane zpravy
95     print "\nIndexy koincidence (bez mezer):"
96     print koincidence.tabulka_indexu(zprava)
97
98 # Vigenere
99 if 'V' in opsny:
100     print "\nHeslo k Vigenerovi (" + opsny[-1] + "):"
101     vig_heslo, vig_text = vigenere.vsechno(zprava, int(opsny[-1]))
102     print vig_heslo
103     print vig_text
104
105 # Jakobsen
106 if mod_m:
107     print "\nJakobsen (s mezerami):"
108     print jakobsen.desifruj(zprava)
109 if mod_x:
110     print "\nJakobsen (bez mezer):"
111     print jakobsen.desifruj(zprava, False)
112
113 # Posuny v abecede
114 (posun, posunuty_text) = posuny.nejlepsi(zprava)
115 if 'P' in opsny or 'A' in opsny:
116     print "\nPosuny v abecede (nejlepsi posun {0}):".format(posun)
117     print("\n".join("{0:>2} {1}".format(
118                    i + 1, posuny.vsechny(zprava)[i]) for i in range(26)))
119 else:
120     print "\nNejlepsi posun ({0}):".format(posun)
121     print posunuty_text
122
123 # Bigramy
124 if 'B' in opsny or 'A' in opsny:
125     print "\nBigramy podle cetnosti:"
126     bigramy = dict()
127     for i in ABECEDA:
128         for j in ABECEDA:
129             bigramy[i+j] = 0
130     for i in range(0, len(zprava)-1):
131         if zprava[i:i+2] in bigramy:
132             bigramy[zprava[i:i+2]] += 1
133     celkem = sum(bigramy.values())
134     for char in sorted(bigramy, key=bigramy.get, reverse=True):
135         if bigramy[char] == 0:
136             break
137         print('{0} {1:>3} {2:>6.2%}'.format(char, bigramy[char],
138                        float(bigramy[char])/celkem))