Practice answer the following questions and complete the activity:

1. What are some improvements that can be made to our program so that it is even more useful.
2. What are some challenges that could follow from adding this additional functionality?
3. What types of things do you need to be aware of when testing new functionality?
4. Activity: Using the encoding process as a model, create a function that will decipher an encrypted into a plaintext message or encrypt a plaintext message into a ciphertext string.

Second briefly one or two sentences answer question 1-3 from the assignment below are some thoughts for answering each question:
Question 1: Could the program be coded so that a given letter isn't always the same encrypted letter? (Ex. 'A' isn't always encrypted to 'E')?
Question 2: Are there challenges in coding when sometimes 'A' is an 'E' and sometimes 'A' is a different letter? Do you think writing code for 'A' to be any random letter is possible?
Question 3: As a soon to be programmer (We'll start writing our own code in Unit 4), you'll find out that you always need to be aware of whether your program is producing the correct output. Why do you think correct output is important? You can use an example to explain your answer. My example is that I am glad that when I choose a song from my playlist to listen to, that I will hear the song I chose and not some other song that I didn't want to hear.

def encrypt(message):
ciphertext = ""
for x in message:
number = ord(x)# convert the letter to a numeric value
number = number - ord('A') #subtract the unicode for A
number = (number + 4) # add the key
number = number % 26 # find the remainder
number = number + ord('A') # add back the first letter
letter = chr(number)
ciphertext=ciphertext + letter
return (ciphertext)
message = "ZEBRA"
print(encrypt(message))

1 answer

Here’s a structured response to your questions and the encoding activity:

Answers to Questions:

  1. Improvements to the Program: One potential improvement is to implement a polyalphabetic cipher, where each letter can be mapped to different letters in different instances. For example, the letter 'A' could be encrypted to 'E' in one context and 'K' in another, making the encryption more secure and less predictable.

  2. Challenges from Additional Functionality: One major challenge would be maintaining the consistency of the decryption process. If 'A' can become multiple different letters, the decryption function would need to know the specific mapping used during encryption. Implementing a secure way to manage these mappings can complicate the code and may introduce bugs.

  3. Awareness When Testing New Functionality: It’s crucial to verify that the program produces the correct output because errors can lead to significant misunderstandings or unintended behaviors. For instance, in a navigation app, if the program gives incorrect instructions, it could lead to a user getting lost, demonstrating just how critical accurate outputs are for functionality and user trust.

Activity: Encrypt and Decrypt Functions

Here’s a modified version of your example with added functionality for both encryption and decryption using a simple approach. For demonstration purposes, we'll use a basic Caesar cipher with a consistent shift but can be extended to allow for more complex encryption in practice.

import random

# Simple encrypt function with a random shift for each letter
def encrypt(message, shift=4):
    ciphertext = ""
    for x in message:
        if x.isalpha():
            number = ord(x.upper())  # Works only with uppercase letters for simplicity
            number = number - ord('A')  # subtract the unicode for A
            number = (number + shift) % 26  # add the key and ensure it wraps around
            number = number + ord('A')  # add back the unicode for A
            letter = chr(number)
            ciphertext += letter
        else:
            ciphertext += x  # Non-alphabetic characters remain unchanged
    return ciphertext

# Decrypt function
def decrypt(ciphertext, shift=4):
    plaintext = ""
    for x in ciphertext:
        if x.isalpha():
            number = ord(x.upper())
            number = number - ord('A')
            number = (number - shift) % 26  # reverse the shift
            number = number + ord('A')
            letter = chr(number)
            plaintext += letter
        else:
            plaintext += x  # Non-alphabetic characters remain unchanged
    return plaintext

# Testing the functions
message = "ZEBRA"
encrypted_message = encrypt(message)
decrypted_message = decrypt(encrypted_message)

print(f"Original Message: {message}")
print(f"Encrypted Message: {encrypted_message}")
print(f"Decrypted Message: {decrypted_message}")

Explanation of the Code:

  • Encrypt Function: This function takes a plaintext message and shifts each letter by a defined key (default is 4). Non-alphabet characters are left unchanged.
  • Decrypt Function: This function reverses the encryption process by shifting the characters back by the same key.
  • Testing: The code tests both the encryption and decryption functions and prints the results.

With this structure, you can easily adapt the key or extend the model to randomize mappings further for more complex encryption strategies.