Added logging, removed additional implementation of bombe from engima.py
[cipher-tools.git] / bombe.py
index b8971a74b98a5097ba0280e6b472198b11bf5e9b..17d02a6176fb673614bfa0dafc0ee9bddcd275b2 100644 (file)
--- a/bombe.py
+++ b/bombe.py
@@ -2,13 +2,35 @@ import string
 import collections
 import multiprocessing
 import itertools
+import logging
 from enigma import *
 
 
+logger = logging.getLogger('bombe')
+# logger.setLevel(logging.WARNING)
+# logger.setLevel(logging.INFO)
+logger.setLevel(logging.DEBUG)
+
+# create the logging file handler
+fh = logging.FileHandler("enigma.log")
+formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+fh.setFormatter(formatter)
+
+# add handler to logger object
+logger.addHandler(fh)
+
+##################################
+# # Bombe
+##################################
+#
+# Good explanation of [how the bombe worked](http://www.ellsbury.com/enigmabombe.htm) by Graham Ellsbury
+#
+
 Signal = collections.namedtuple('Signal', ['bank', 'wire'])
 Connection = collections.namedtuple('Connection', ['banks', 'scrambler'])
 MenuItem = collections.namedtuple('MenuIem', ['before', 'after', 'number'])
 
+
 def make_menu(plaintext, ciphertext):
     return [MenuItem(p, c, i+1) 
             for i, (p, c) in enumerate(zip(plaintext, ciphertext))]
@@ -92,7 +114,8 @@ class Bombe(object):
                                   self.reflector_spec,
                                   wheel3_pos=unpos(item.number - 1))
             self.add_connection(item.before, item.after, scrambler)
-        most_common_letter = (collections.Counter(m.before for m in menu) +                               collections.Counter(m.after for m in menu)).most_common(1)[0][0]
+        most_common_letter = (collections.Counter(m.before for m in menu) +\
+            collections.Counter(m.after for m in menu)).most_common(1)[0][0]
         self.test_start = Signal(most_common_letter, most_common_letter)
         
     def set_positions(self, wheel1_pos, wheel2_pos, wheel3_pos):
@@ -126,6 +149,7 @@ class Bombe(object):
         while self.pending:
             current = self.pending[0]
             # print("processing", current)
+            logger.debug("Propogater processing {}".format(current))
             self.pending = self.pending[1:]
             if not self.banks[current.bank][current.wire]:
                 self.banks[current.bank][current.wire] = True
@@ -136,6 +160,7 @@ class Bombe(object):
                         other_bank = [b for b in c.banks if b != current.bank][0]
                         other_wire = c.scrambler.lookup(current.wire)
                         # print("  adding", other_bank, other_wire, "because", c.banks)
+                        logger.debug("Propogator adding {0} {1} because {2}".format(other_bank, other_wire, c.banks))
                         self.pending += [Signal(other_bank, other_wire)]
     
     def run(self, run_start=None, wheel1_pos='a', wheel2_pos='a', wheel3_pos='a', use_diagonal_board=True):