nouzove pouzitelna verze
[krypto.git] / jakobsen.py
index 1913a27..8b4739a 100644 (file)
@@ -29,12 +29,12 @@ def vzdalenost(tab1, tab2, abc=MABECEDA):
             rozdil += abs(tab1[i][j] - tab2[i][j])
     return rozdil
 
-def substituce(zprava, slovnik, abc=MABECEDA):
+def substituce(zprava, slovnik):
     """Vrati zpravu, ve ktere jsou znaky dane abecedy nahrazenypodle daneho
     slovniku."""
     pole = []
     for char in zprava:
-        if char in abc:
+        if char in slovnik:
             pole.append(slovnik[char])
         else:
             pole.append(char)
@@ -53,12 +53,22 @@ def poradi_dle_frekvence(zprava, abc=MABECEDA):
 class reference:
     pass
 
+def kombinace(abeceda):
+    a = 0
+    b = 1
+    while b < len(abeceda):
+        yield (abeceda[a], abeceda[a + b])
+        a += 1
+        if a + b == len(abeceda):
+            a = 0
+            b += 1
+
 def jakobsen(zprava, ref):
     """Pro danou sifrovanou zpravu vrati substitucni slovnik odvozeny s pomoci
     Jakobsenova algoritmu s danou referencni tabulkou."""
     slovnik = dict(zip(poradi_dle_frekvence(zprava, ref.abeceda), ref.poradi))
     tabulka = nova_tabulka(
-                  substituce(zprava, slovnik, ref.abeceda),
+                  substituce(zprava, slovnik),
                   ref.abeceda
                   )
     vzdal = vzdalenost(tabulka, ref.tabulka, ref.abeceda)
@@ -66,16 +76,17 @@ def jakobsen(zprava, ref):
     vzdal_old = vzdal + 1
     while vzdal_old > vzdal:
         vzdal_old = vzdal
-        for (x, y) in combinations(ref.abeceda, 2):
+        for (x, y) in kombinace(ref.poradi):
             slovnik[x], slovnik[y] = slovnik[y], slovnik[x]
             nova_vzdalenost = vzdalenost(
                      nova_tabulka(
-                         substituce(zprava, slovnik, ref.abeceda),
+                         substituce(zprava, slovnik),
                          ref.abeceda),
                      ref.tabulka,
                      ref.abeceda)
             if  nova_vzdalenost < vzdal:
                 vzdal = nova_vzdalenost
+                break
             else:
                 slovnik[x], slovnik[y] = slovnik[y], slovnik[x]
     return slovnik
@@ -90,6 +101,6 @@ def desifruj(zprava, mezery=True):
     ref = pickle.load(soubor)
     soubor.close()
     slovnik = jakobsen(ocesat(zprava, mezery), ref)
-    return '\n'.join([''.join(substituce(zprava, slovnik, ref.abeceda)),
+    return '\n'.join([''.join(substituce(zprava, slovnik)),
                       ' '.join(ref.abeceda),
                       ' '.join([slovnik[c] for c in ref.abeceda])])