3.4 Transposition Cipher

3.4.1 Encrypting Using Transposition

One way to scramble the letters of a message is to separate the message into two groups of characters, where the first group is composed of the even-numbered characters and the second group is composed of the odd-numbered characters. If we create one string out of the even-numbered characters and another out of the odd-numbered characters, we can concatenate the two new strings together to form the ciphertext string. Because this results in a string with the characters shuffled to new positions, we call this a transposition cipher, also sometimes called the rail fence cipher. FIGURE 3.3 illustrates the idea behind this encryption algorithm.

“A figure illustrates encrypting a string using an even-odd shuffle.

FIGURE 3.3 Encrypting a string using an even–odd shuffle.

Now that we have a scheme for scrambling the plaintext message, let’s write a Python function that takes the plaintext message as a parameter and returns the ciphertext message. The key to this algorithm lies in our ability to put the even characters from the plaintext into one string and the odd characters into another. One way to do this is to use a counter and a string iterator. A string iterator is a for loop in which the loop variable takes on the value of each character in the string.

The string iterator uses this form of the for loop:

Image

With each iteration of the for loop, the loop variable ch takes on the value of the next character in the string stringVariable. So, for the first iteration, ch becomes the character at index 0 of stringVariable; for the second iteration, ch becomes the character at index 1 of stringVariable; and so on.

As we iterate over each character of the string, we increment our counter. If the counter is an even number, we concatenate the current character to our even-character string. If the counter is odd, we concatenate the character to our odd-character string. In this so-called rail fence cipher, each rail contains part of the original string. In this case, because we are dividing the string into two parts, we call it a two-rail cipher.

How can we tell if a number is even or odd? Recall that for any even number N, when you divide N by 2, there is no remainder. For any odd number N, N divided by 2 has a remainder of 1. In Python, we can obtain the remainder by using the modulo operator. For any even number N, N % 2 is 0. For any odd number N, N % 2 is 1. We can use the expression charCount % 2 == 0 as the condition in an if statement to test whether the character counter is even or odd. LISTING 3.2 shows the encryption algorithm using the strategy described here.

Image

LISTING 3.2 Scrambling a plaintext message

The scramble2Encrypt function makes use of the accumulator pattern in several different places. First, evenChars and oddChars start as empty strings and accumulate characters as the for loop executes. The accumulator pattern works just as well for concatenating strings as it does for adding numbers. When we apply the accumulator pattern to strings, we build up a string that starts from nothing (the empty string, ""), growing the string one character at a time. The next use of the accumulator pattern is a familiar numeric accumulator using the charCount variable.

On line 5 of Listing 3.2 we begin a loop that will iterate over each character in the plainText string. When we iterate over a string, the loop variable references each character in the string one after another. On line 6, we make use of the test we devised to decide whether charCount is even or odd. If charCount is even, we concatenate the current character referenced by the loop variable ch to the existing value of evenChars. Because concatenation creates a new string, evenChars becomes this newly constructed string when we perform the assignment. If charCount is odd, we concatenate oddChars and ch to create a new string referenced by oddChars.

Finally, after all characters in the plaintext string have been processed, on line 11 we create the cipherText string by concatenating oddChars and evenChars. The order of variables in the concatenation is not accidental. We put oddChars first for a reason: If our string has an odd number of characters, oddChars will be one character shorter than the number of even characters. Can you explain why? We will see in a moment that this point is important when we want to split the ciphertext back into two pieces.

SESSION 3.10 shows the output of the scramble2Encrypt function for five different test inputs. Notice that some of the test cases are just nonsense strings, but they are chosen carefully to make it easy to see if the function is working the way we think it should. Also notice that we test some boundary cases such as a string of length 1 and even an empty string.

Image

SESSION 3.10 Testing scramble2Encrypt

3.4.2 Decrypting a Transposed Message

Our next task is to write a function to decrypt a message that was encrypted by our scramble2Encrypt function. The input to our decryption function will be the ciphertext produced by our encryption function. The decrypt function will return the restored plaintext copy of the string.

To restore the plaintext string, we start by splitting the ciphertext in half. The first half of the string contains the odd characters from our original message, and the second half of the string contains the even characters. To restore the plaintext version of the string, we start with an empty plaintext string and concatenate the characters from the even and odd strings onto the end of the plaintext string. We alternate taking a character from the even string first, then the odd string, and so on. FIGURE 3.4 gives an example of putting the plaintext back together again.

“A figure shows decrypting a message by alternating characters from the ciphertext.”

FIGURE 3.4 Decrypting a message by alternating characters from the ciphertext.

One detail to consider when reconstructing the plaintext message is that we may have one more character in the even-character string than we do in the odd-character string. We can easily check for this by comparing the lengths of the two strings. If the odd-numbered character string is shorter than the even-numbered character string, we simply concatenate the last character from the even string onto the plaintext. LISTING 3.3 shows the Python code for implementing the decryption function.

Image

LISTING 3.3 Decrypting a transposed message

To split the ciphertext string into two halves, we use the slicing operator, as shown on lines 3 and 4 of Listing 3.3. To find the middle of the string, we use integer division to divide the length of the string by 2. We use a simple slicing operator shortcut on these lines. Recall that when the number is omitted before the :, the slice operator starts at the beginning of the string; in contrast, when the number after the : is omitted, the slice operation continues until the end of the string.

In the loop that starts on line 7, we use the string indexing operator to get the next character from each of the two halves. Once again, we are using an accumulator pattern to build the plaintext string. Finally, on lines 11 and 12, we check for the case in which the number of characters in the ciphertext is odd, which would make the evenChars string longer than the oddChars string. If so, we add the final character from evenChars to the end of the plaintext string.

SESSION 3.11 shows how you can test the decrypt function. Notice that since scramble2Encrypt returns a string, we can use the function call directly as a parameter to the scramble2Decrypt function. In essence, we are passing the return value from scramble2Encrypt to the scramble2Decrypt function. It is easy to test whether the decryption function works because it should return the exact same string that we provided as a parameter to the encryption function. Once again, we have tried an easy case, plus several boundary cases.

Image

SESSION 3.11 Testing encryption and decryption

Note that in the last test, we cannot fit the entire string on one line. To indicate that we are not finished with the statement we want to execute and that the statement is continued on the next line, we use the backslash continuation character ().

3.4.3 Asking for Input

Now that we have functions for encrypting and decrypting a message, it would be nice if we had an easier way to get a message to encrypt. Most programs today use a dialog box as a way of asking the user for some input. While Python provides a way to create dialog boxes, it also makes a much simpler method available to us. That is, Python provides a function that allows us to ask a user to enter some data and returns a reference to the data in the form of a string. This function is called input.

As shown in TABLE 3.5, Python’s built-in input function takes a single parameter that is a string. This string is often called the prompt because it contains some helpful text prompting the user to enter something. For example, you might call input as follows: msg = input('Enter a message to encrypt: '). This causes the prompt string to be displayed; Python then waits for the user to type something, followed by pressing the enter or return key. Whatever the user types after the prompt will be stored in the msg variable.

TABLE 3.5 The input Function

Function Description
input(prompt) Outputs the prompt, then returns a string containing any characters typed by the user when the user presses enter or return. The enter or return key is not part of the returned string.

Using the input function, we can easily write another function that will prompt the user to enter a message and then print the encrypted version of the message. LISTING 3.4 illustrates how to incorporate input into your program, and SESSION 3.12 shows the result of calling our encryptMessage function.

Image

LISTING 3.4 Using input

Image

SESSION 3.12 Using the input function

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.2.212