novy slovnik substantiv
[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 def analyza(zprava, opsny):
18     analyza = []
19
20     # Prepinani spacemodu
21     mod_m = False
22     mod_x = False
23     if 'X' in opsny:
24         mod_x = True
25     if 'M' in opsny:
26         mod_m = True
27     if 'A' in opsny:
28         mod_x = True
29         mod_m = True
30     if not mod_m and not mod_x:
31         if ' ' in ocesat(zprava, True)[1:-1]:
32             mod_m = True
33             analyza.append("Automaticky zvolena analyza s mezerami.")
34         else:
35             mod_x = True
36             analyza.append("Automaticky zvolena analyza bez mezer.")
37         
38     # Zakladni udaje
39     analyza.append("\nZakladni udaje:")
40     if mod_m:
41         analyza.append("Delka zpravy (vcetne mezer a zvlastnich znaku: " +
42             str(len(zprava)))
43     analyza.append("Delka zpravy (bez mezer a zvlastnich znaku): " +
44         str(len(ocesat(zprava, False))))
45
46     # Prumerna delka slova
47     if mod_m:
48         analyza.append("\nPrumerna delka slova:")
49         slova = ocesat(zprava, True).split()
50         analyza.append('{0:.3}'.format(float(sum([len(word) for word in slova]))/len(slova)))
51
52     # Frekvence znaku 
53     analyza.append("\nFrekvencni analyza:")
54     freq = dict()
55     for char in ABECEDA:
56         freq[char] = 0
57     for char in zprava:
58         if char in freq:
59             freq[char] += 1
60     celkem = sum(freq.values())
61     for char in sorted(freq, key=freq.get, reverse=True):
62         analyza.append('{0} {1:>3} {2:>6.2%}'.format(char, freq[char],
63                        float(freq[char])/celkem))
64
65     # Index koincidence
66     if mod_m:
67         analyza.append("\nIndex koincidence (s mezerami):")
68         analyza.append('{0:.2%}'.format(
69                        koincidence.index_koincidence(zprava, True)))
70     if mod_x and len(zprava) >= 30:
71         #TODO tady by se spravne mela porovnavat delka ocesane zpravy
72         analyza.append("\nIndexy koincidence (bez mezer):")
73         analyza.append(koincidence.tabulka_indexu(zprava))
74
75     # Vigenere
76     if 'V' in opsny:
77         analyza.append("\nHeslo k Vigenerovi (" + opsny[-1] + "):")
78         vig_heslo, vig_text = vigenere.vsechno(zprava, int(opsny[-1]))
79         analyza.append(vig_heslo)
80         analyza.append(vig_text)
81
82     # Jakobsen
83     if mod_m:
84         analyza.append("\nJakobsen (s mezerami):")
85         analyza.append(jakobsen.desifruj(zprava))
86     if mod_x:
87         analyza.append("\nJakobsen (bez mezer):")
88         analyza.append(jakobsen.desifruj(zprava, False))
89
90     # Posuny v abecede
91     (posun, posunuty_text) = posuny.nejlepsi(zprava)
92     if 'P' in opsny or 'A' in opsny:
93         analyza.append("\nPosuny v abecede (nejlepsi posun {0}):".format(posun))
94         analyza.append("\n".join("{0:>2} {1}".format(
95                        i + 1, posuny.vsechny(zprava)[i]) for i in range(26)))
96     else:
97         analyza.append("\nNejlepsi posun ({0}):".format(posun))
98         analyza.append(posunuty_text)
99
100     # Bigramy
101     if 'B' in opsny or 'A' in opsny:
102         analyza.append("\nBigramy podle cetnosti:")
103         bigramy = dict()
104         for i in ABECEDA:
105             for j in ABECEDA:
106                 bigramy[i+j] = 0
107         for i in range(0, len(zprava)-1):
108             if zprava[i:i+2] in bigramy:
109                 bigramy[zprava[i:i+2]] += 1
110         celkem = sum(bigramy.values())
111         for char in sorted(bigramy, key=bigramy.get, reverse=True):
112             if bigramy[char] == 0:
113                 break
114             analyza.append('{0} {1:>3} {2:>6.2%}'.format(char, bigramy[char],
115                            float(bigramy[char])/celkem))
116     return '\n'.join(analyza)
117
118 if __name__ == '__main__':
119     if len(sys.argv) > 1:
120         opsny = sys.argv[1]
121     else:
122         opsny = ''
123
124     telo = sys.stdin.read()
125     zprava = telo.strip().upper()
126     print(analyza(zprava, opsny))
127