changeset 41:dae8d52023e7

Decrypt command-line command working. Fixed bug in the encrypt procedure's padding.
author Brian Neal <bgneal@gmail.com>
date Sun, 30 Jun 2013 20:26:32 -0500
parents 987a29d8bce3
children 96fe2240936d
files m209/main.py m209/procedure.py m209/tests/test_procedure.py
diffstat 3 files changed, 44 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/m209/main.py	Sun Jun 30 18:30:31 2013 -0500
+++ b/m209/main.py	Sun Jun 30 20:26:32 2013 -0500
@@ -137,7 +137,35 @@
 
 def decrypt(args):
     """Decrypt subcommand processor"""
-    print('Decrypting!', args)
+    logging.info("Decrypting using key file %s", args.file)
+
+    # Check for key list file
+    if not os.path.isfile(args.file):
+        sys.exit("key list file not found: {}\n".format(args.file))
+
+    # Read contents of ciphertext file
+    if args.ciphertext == '-':
+        msg = sys.stdin.read()
+    else:
+        with open(args.ciphertext, 'r') as fp:
+            msg = fp.read()
+
+    msg = msg.strip()
+
+    # Start the decrypt procedure
+    proc = StdProcedure()
+    params = proc.set_decrypt_message(msg)
+
+    # Find a key list for the message
+    key_list = read_key_list(args.file, params.key_list_ind)
+    if key_list is None:
+        sys.exit("Could not find key list {} in {}\n".format(
+            params.key_list_ind, args.file))
+
+    # Install the key list and perform the decrypt operation
+    proc.set_key_list(key_list)
+    plaintext = proc.decrypt()
+    print(plaintext)
 
 
 def keygen(args):
@@ -195,10 +223,10 @@
     # create the sub-parser for decrypt
     dec_parser = subparsers.add_parser('decrypt', aliases=['de'],
         help='decrypt text')
-    dec_parser.add_argument('-k', '--keylist', default=DEFAULT_KEY_LIST,
+    dec_parser.add_argument('-f', '--file', default=DEFAULT_KEY_LIST,
         help='path to key list file [default: %(default)s]')
-    dec_parser.add_argument('-c', '--ciphertext',
-        help='ciphertext string to decrypt; prompted if omitted')
+    dec_parser.add_argument('-c', '--ciphertext', default='-',
+        help='path to ciphertext file or - for stdin [default: %(default)s]')
     dec_parser.set_defaults(subcommand=decrypt)
 
     # create the sub-parser for generating key lists
--- a/m209/procedure.py	Sun Jun 30 18:30:31 2013 -0500
+++ b/m209/procedure.py	Sun Jun 30 20:26:32 2013 -0500
@@ -153,12 +153,11 @@
         # If the final group in the ciphertext has less than 5 letters, pad with
         # X's to make a complete group:
 
-        total_len = len(ciphertext)
-        num_groups = total_len // 5
-        num_spaces = num_groups - 1 if num_groups >= 2 else 0
-        x_count = 5 - (total_len - num_spaces) % 5
-        if 0 < x_count < 5:
-            ciphertext = ciphertext + 'X' * x_count
+        i = ciphertext.rfind(' ')
+        if i != -1:
+            x_count = 6 - (len(ciphertext) - i)
+            if x_count:
+                ciphertext = ciphertext + 'X' * x_count
 
         # Add the message indicators to pad each end of the message
 
--- a/m209/tests/test_procedure.py	Sun Jun 30 18:30:31 2013 -0500
+++ b/m209/tests/test_procedure.py	Sun Jun 30 20:26:32 2013 -0500
@@ -45,6 +45,13 @@
         plaintext = self.proc.decrypt()
         self.assertEqual(plaintext[:len(PLAINTEXT)], PLAINTEXT)
 
+    def test_encrypt_padding(self):
+        pt = 'THE PIZZA HAS ARRIVED STOP WILL PLAY DAYZ AFTER SUPPER STOP'
+        ct = self.proc.encrypt(pt)
+        groups = ct.split()
+        counts_good = [len(group) == 5 for group in groups]
+        self.assertTrue(all(counts_good))
+
     def test_blair_decrypt(self):
 
         ciphertext = (