changeset 13:2e3d919383dd

Fixed bug in stepping logic. 216 letter test now passes.
author Brian Neal <bgneal@gmail.com>
date Sun, 01 Dec 2013 20:30:06 -0600
parents 7d32247eab5e
children eea5734a1655
files purple/machine.py purple/tests/test_machine.py
diffstat 2 files changed, 18 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/purple/machine.py	Sun Dec 01 16:56:45 2013 -0600
+++ b/purple/machine.py	Sun Dec 01 20:30:06 2013 -0600
@@ -10,6 +10,9 @@
 Sullivan, and Frode Weierud. This paper was published in Cryptologia, Volume 27,
 Issue 1, January, 2003, pp. 1-43.
 
+The paper is also available at:
+http://cryptocellar.web.cern.ch/cryptocellar/pubs/PurpleRevealed.pdf
+
 """
 from collections import Counter
 import string
@@ -197,11 +200,16 @@
 
             plaintext.append(self.alphabet[x])
 
-            # Now step the switches.
-            # The sixes switch steps every letter.
-            sixes_pos = self.sixes.step()
+            # Now step the switches. First read the sixes and middle switch
+            # positions before stepping anything. Use these latched values in
+            # the decision processes for stepping a twenties. This is crucial!
+            sixes_pos = self.sixes.pos
             middle_pos = self.middle_switch.pos
 
+            # Now we can step the sixes. It unconditionally steps after every
+            # letter is processed.
+            self.sixes.step()
+
             # Only 1 twenties switch steps at a time.
             #
             # Normally the fast switch advances every letter.
@@ -230,7 +238,7 @@
             # Here we see the fast switch stepping. However at (*) both the
             # sixes and middle switch have reached their last positions, so the
             # slow switch steps. At the next letter (#) the middle switch plays
-            # "catch up" and advances.
+            # "catch up" and advances while the fast switch holds steady.
 
             if sixes_pos == 24 and middle_pos == 24:
                 self.slow_switch.step()
--- a/purple/tests/test_machine.py	Sun Dec 01 16:56:45 2013 -0600
+++ b/purple/tests/test_machine.py	Sun Dec 01 20:30:06 2013 -0600
@@ -104,17 +104,10 @@
             "ZCKQTSHXTIJCNWXOKUFNQR-TAOIHWTATWV"
         )
 
-        ciphertext = """\
-ZTXOD NWKCC MAVNZ XYWEE TUQTC IMNVE UVIWB LUAXR RTLVA
-RGNTP CNOIU PJLCI VRTPJ KAUHV MUDTH KTXYZ ELQTV WGBUH FAWSH
-ULBFB HEXMY HFLOW D-KWH KKNXE BVPYH HGHEK XIOHQ HUHWI KYJYH
-PPFEA LNNAK IBOOZ NFRLQ CFLJT TSSDD OIOCV T-ZCK QTSHX TIJCN
-WXOKU FNQR- TAOIH WTATW V"""
-        ciphertext = ''.join(ciphertext.split())
         self.assertEqual(216, len(ciphertext))
 
         # Use 'X' in place of the garbles
-        input_text = ciphertext.replace('-', 'A')
+        input_text = ciphertext.replace('-', 'X')
 
         plaintext = (
             "FOVTATAKIDASINIMUIMINOMOXIWO"
@@ -124,6 +117,7 @@
             "BYAGENUINEDESIRETOCOMETOANAMICABLEUNDERSTANDIN-"
             "WITHTHEGOVERNMENTOFTHE-NITEDSTATES"
         )
+        self.assertEqual(len(ciphertext), len(plaintext))
 
         # Decrypt
         purple = Purple97.from_key_sheet(
@@ -131,15 +125,15 @@
                 alphabet='NOKTYUXEQLHBRMPDICJASVWGZF')
 
         actual = purple.decrypt(input_text)
-        print(actual)
 
         mismatches = []
         for n, (a, b) in enumerate(zip(plaintext, actual)):
             if a != b and a != '-':
                 mismatches.append(n)
 
-        print("There are {} mismatches".format(len(mismatches)))
+        msg = None
         if mismatches:
-            print("mismatches = {}".format(mismatches))
+            msg = "There are {} mismatches: {}".format(len(mismatches),
+                    mismatches)
 
-        self.assertTrue(len(mismatches) == 0)
+        self.assertTrue(len(mismatches) == 0, msg)