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