merge
[krypto.git] / posuny.py
1 """Modul pro praci s posuny v abecede."""
2
3 from referencni import reference
4 from ocesavac import ocesat
5 from spolecne import ABECEDA
6
7 def posun(char, pos=1):
8     """Pokud dostane velke pismeno, vrati pismeno ktere je od nej vzdaleno
9     'pos' mist v abecede. Jinak vrati puvodni pismeno."""
10     if 65 <= ord(char) < 91 - pos:
11         return chr(ord(char) + pos)
12     if ord(char) < 91 and ord(char) >= 91 - pos:
13         return chr(ord(char) + pos - 26)
14     else:
15         return char
16
17 def vsechny(zprava):
18     """Pro danou zpravu (libovolny text vsetne zvlastnich znaku) vrati
19     vsechny jeji posuny v abecede."""
20     posunuty = zprava.upper()
21     analyza = []
22     for _ in range(26):
23         posunuty = [posun(char) for char in  posunuty]
24         analyza.append(''.join(posunuty))
25     return analyza
26
27 def eu_vzdalenost(vec1, vec2):
28     """Euklidovska vzdalenost dvou vektoru."""
29     return sum([(x - y)**2 for (x, y) in zip(vec1, vec2)])
30
31 def nejlepsi(text):
32     """Vrati text (neocesany) posunuty tak, aby mel frekvence znaku co
33     nejblizsi cestine bez mezer."""
34     posunuti = nej_posun(text)
35     return (posunuti, ''.join([posun(char, posunuti) for char in text.upper()]))
36
37 def nej_posun(text):
38     """Vrati pocet znaku v abecede, o ktere by se mel text posunout, aby mel
39     frekvence znaku co nejblize cestine bez mezer."""
40     ref = referencni.nacti('bref')
41     freq = dict()
42     for char in ocesat(text, False):
43         freq[char] = freq.get(char, 0) + 1
44     celkem = sum(freq.values())
45     frekv = [float(freq.get(char, 0))/celkem for char in ABECEDA]
46     vzdalenost = eu_vzdalenost(frekv, ref.frekvence)
47     posunuti = 0
48     for i in range(1, 26):
49         frekv = [frekv[25]] + frekv[:-1]
50         nova_vzdalenost = eu_vzdalenost(frekv, ref.frekvence)
51         if nova_vzdalenost < vzdalenost:
52             vzdalenost = nova_vzdalenost
53             posunuti = i
54     return posunuti