From ca11fa5f32b87dc515e494624e4f5b7b47a3a7f9 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 26 Nov 2009 08:44:05 -0500 Subject: [PATCH] replacing magic numbers with consts, opting for list-based rather than string-based stuff in most places --- onetimepad.py | 28 ++++++++++++++++++++-------- test_onetimepad.py | 15 ++++++++++----- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/onetimepad.py b/onetimepad.py index f027170..ab0e120 100644 --- a/onetimepad.py +++ b/onetimepad.py @@ -1,5 +1,10 @@ import random +PAD_MODULO = 3 +DEFAULT_PAD_WIDTH = 72 +CIPHER_FLOOR = 1 +CIPHER_CEIL = 25 + def encode(msg, pad): return msg @@ -9,27 +14,34 @@ def decode(msg, pad): return msg -def create_pad(length, width=72): +def create_pad(length, width=DEFAULT_PAD_WIDTH): + return '\n'.join(create_pad_lines(length, width=width)) + + +def create_pad_lines(length, width=DEFAULT_PAD_WIDTH): chars = _create_chars_for_pad(length) lines = _chunk_chars_into_lines(chars, width=width) - return '\n\n\n'.join(lines) + for line in lines: + yield line + yield '' + yield '' def _create_chars_for_pad(length): chars = [] for char in range(length): - chars.append(_AS_ALPHA[random.randint(1, 25)]) + chars.append(_AS_ALPHA[random.randint(CIPHER_FLOOR, CIPHER_CEIL)]) return ''.join(chars) -def _chunk_chars_into_lines(chars, width=72): +def _chunk_chars_into_lines(chars, width=DEFAULT_PAD_WIDTH): lines = [] for chunk in _as_line_chunks(chars, width=width): lines.append(chunk) return lines -def _as_line_chunks(chars, width=72): +def _as_line_chunks(chars, width=DEFAULT_PAD_WIDTH): chunk = [] for char in chars: chunk.append(char) @@ -57,11 +69,11 @@ def _get_textwidth(text): def _is_padline(lineno): - return not lineno % 3 + return not lineno % PAD_MODULO def _is_txtline(lineno): - return (lineno % 2 and not lineno % 3) + return (lineno % 2 and not lineno % PAD_MODULO) def _is_cipherline(lineno): @@ -73,7 +85,7 @@ def _mk_as_alpha(): a_chr = ord('A') past_j = False - for char in range(26): + for char in range(CIPHER_CEIL + 1): letter = chr(a_chr + char) if letter != 'J': key = char + (1 if not past_j else 0) diff --git a/test_onetimepad.py b/test_onetimepad.py index ca8480d..a1f4d8f 100644 --- a/test_onetimepad.py +++ b/test_onetimepad.py @@ -5,6 +5,7 @@ import onetimepad as OT class TestOneTimePad(unittest.TestCase): msg = ('HOWMUCHCHUCKCOULDAWOODCHUCKCHUCKIFA' 'WOODCHUCKCOULDCHUCKWOOD' * 50) + _padsize = 2000 def test_mk_as_alpha_excludes_j(self): self.assertTrue('J' not in OT._AS_ALPHA.values()) @@ -14,13 +15,17 @@ class TestOneTimePad(unittest.TestCase): def test_creates_pad_of_desired_length(self): for width in (72, 33, 99, 111): - pad = OT.create_pad(2000, width=width) - lines = [line.strip('.') for line in pad.split('\n\n\n')] - self.assertEqual(2000, len(''.join(lines))) + pad = OT.create_pad(self._padsize, width=width) + lines = [line.strip('.') for line in pad.split()] + actual = len(''.join(lines)) + self.assertEqual(self._padsize, len(''.join(lines)), + 'pad of {0} chars created at width ' + '{1}, actual={2}'.format(self._padsize, + width, actual)) def test_two_out_of_every_three_lines_are_empty_on_new_pad(self): - pad = OT.create_pad(2000) - for lineno, line in enumerate(pad.splitlines()): + pad = OT.create_pad_lines(2000) + for lineno, line in enumerate(pad): line = line.strip() if OT._is_padline(lineno): self.assertTrue(bool(len(line)),