Source code for src.ch05.p1_encode_null

"""Encode a message in a list using a null cipher."""
import os
from src.ch01.challenge.c2_name_generator import build_name_list, split_names
from src.ch04.challenge.c1_encode_route import format_plaintext


[docs]def encode_null(message: str, word_list: list) -> list: """Encode plaintext message with null cipher. Embed **message** in a list of words using **word_list**. Use second letter in first word of cipherlist, then third letter in second word of cipherlist, and repeat until **message** is embedded in cipherlist. Args: message (str): Message to encrypt with null cipher. Spaces and punctuation are okay, but will be removed. Uppercase converted to lowercase. word_list (list): List of words to build cipherlist. The more the merrier. Returns: List of words with **message** embedded as described. Context is *not* provided. Raises: ValueError: if the list of names doesn't have a name with the needed letter. """ message = ''.join(format_plaintext(message)) cipherlist = [] for letter in message: for word in word_list: if all([len(word) > 2, word not in cipherlist]): # Even numbered word, use second letter. if len(cipherlist) % 2 == 0 and \ word[1].lower() == letter: cipherlist.append(word) break # Odd numbered word, use third letter. elif len(cipherlist) % 2 != 0 and \ word[2].lower() == letter: cipherlist.append(word) break if word == word_list[-1]: if len(cipherlist) % 2 == 0: place = 'second' else: place = 'third' raise ValueError(f'Missing word with {place} letter of: ' f'{letter}') return cipherlist
[docs]def main(): """Demonstrate null cipher encoder. Encode a message in a list of last names. First last name in list isn't used and some unused last names are added near the beginning of the list. Tip: The website `bestwordlist.com`_ helped with the missing names. .. _bestwordlist.com: https://www.bestwordlist.com """ message = 'Say the word and we riot' # Build last names from Chapter 1 name generator. folder = os.path.abspath('../../src/ch01/challenge/c2files/') last_names = split_names(build_name_list(folder))['last'] # Add missing names for message. last_names.extend(['Asher', 'Dwiles', 'Stone']) # Insert unused last names near beginning of cipherlist. cipherlist = encode_null(message, last_names) for name in last_names: if name not in cipherlist: cipherlist.insert(0, name) break cipherlist.insert(4, 'Scrooge') cipherlist.insert(7, 'Nero') # Output encrypted message with context. print('Hi Mom,\n\nPlease send me stamps, labels, and stationery to write ' 'thank you cards for the\nfollowing families:\n') print(*cipherlist, sep='\n') print('\nThanks so much for everything.\n\nLuv ya\' lots,\n\nJohn Doe')
if __name__ == '__main__': main()