Опубликован: 12.07.2013 | Уровень: специалист | Доступ: платный
Лекция 14:

Caesar Cipher

< Лекция 13 || Лекция 14: 12 || Лекция 15 >
Аннотация: The program in this chapter is not really a game, but it is fun to play with nonetheless. Our program will convert normal English into a secret code, and also convert secret codes back into regular English again.

Topics Covered In This Chapter:

  • Cryptography and ciphers
  • Encrypting and decrypting
  • Ciphertext, plaintext, keys, and symbols
  • The Caesar Cipher
  • ASCII ordinal values
  • The chr() and ord() functions
  • The isalpha() string method
  • The isupper() and islower() string methods
  • Cryptanalysis
  • The brute force technique

The program in this chapter is not really a game, but it is fun to play with nonetheless. Our program will convert normal English into a secret code, and also convert secret codes back into regular English again. Only someone who is knowledgeable about secret codes will be able to understand our secret messages.

Because this program manipulates text in order to convert it into secret messages, we will learn several new functions and methods that come with Python for manipulating strings. We will also learn how programs can do math with text strings just as it can with numbers.

About Cryptography

The science of writing secret codes is called cryptography. Cryptography has been used for thousands of years to send secret messages that only the recipient could understand, even if someone captured the messenger and read the coded message. A secret code system is called a cipher. There are thousands of different ciphers that have been used, each using different techniques to keep the messages a secret.

In cryptography, we call the message that we want to be secret the plaintext. The plaintext could look something like this:

Hello there! The keys to the house are hidden under the reddish flower pot.

When we convert the plaintext into the encoded message, we call this encrypting the plaintext. The plaintext is encrypted into the ciphertext. The ciphertext looks like random letters (also called garbage data), and we cannot understand what the original plaintext was by just looking at the ciphertext. Here is an example of some ciphertext:

Ckkz fkx kj becqnejc kqp pdeo oaynap iaoowca!

But if we know about the cipher used to encrypt the message, we can decrypt the ciphertext back to the plaintext. (Decryption is the opposite of encryption.)

Many ciphers also use keys. Keys are secret values that let you decrypt ciphertext that was encrypted using a specific cipher. Think of the cipher as being like a door lock. Although all the door locks of the same type are built the same, but a particular lock will only unlock if you have the key made for that lock.

The Caesar Cipher

When we encrypt a message using a cipher, we will choose the key that is used to encrypt and decrypt this message. The key for our Caesar Cipher will be a number from 1 to 26. Unless you know the key (that is, know the number), you will not be able to decrypt the encrypted message.

The Caesar Cipher was one of the earliest ciphers ever invented. In this cipher, you encrypt a message by taking each letter in the message (in cryptography, these letters are called symbols because they can be letters, numbers, or any other sign) and replacing it with a "shifted" letter. If you shift the letter A by one space, you get the letter B. If you shift the letter A by two spaces, you get the letter C. Figure 14.1 is a picture of some letters shifted over by 3 spaces.

Shifting over letters by three spaces. Here, B becomes E.

Рис. 14.1. Shifting over letters by three spaces. Here, B becomes E.

To get each shifted letter, draw out a row of boxes with each letter of the alphabet. Then draw a second row of boxes under it, but start a certain number of spaces over. When you get to the leftover letters at the end, wrap around back to the start of the boxes. Here is an example with the letters shifted by three spaces:

The entire alphabet shifted by three spaces.

увеличить изображение
Рис. 14.2. The entire alphabet shifted by three spaces.

The number of spaces we shift is the key in the Caesar Cipher. The example above shows the letter translations for the key 3.

Using a key of 3, if we encrypt the plaintext "Howdy", then the "H" becomes "E". The letter "o" becomes "l". The letter "w" becomes "t". The letter "d" becomes "a". And the letter "y" becomes "v". The ciphertext of "Howdy" with key 3 becomes "Eltav".

We will keep any non-letter characters the same. In order to decrypt "Eltav" with the key 3, we just go from the bottom boxes back to the top. The letter "E" becomes "H", the letter "l" becomes "o", the letter "t" becomes "w", the letter "a" becomes "d", and the letter "v" becomes "y" to form "Howdy".

You can find out more about the Caesar Cipher from Wikipedia at http://en.wikipedia.org/wiki/Caesar_cipher

ASCII, and Using Numbers for Letters

How do we implement this shifting of the letters in our program? We can do this by representing each letter as a number (called an ordinal), and then adding or subtracting from this number to form a new number (and a new letter). ASCII (pronounced "ask-ee" and stands for American Standard Code for Information Interchange) is a code that connects each character to a number between 32 and 127. The numbers less than 32 refer to "unprintable" characters, so we will not be using them.

The capital letters "A" through "Z" have the ASCII numbers 65 through 90. The lowercase letters "a" through "z" have the ASCII numbers 97 through 122. The numeric digits "0" through "9" have the ASCII numbers 48 through 57.

Таблица 14.1. The ASCII Table
32 (space) 48 0 64 @ 80 P 96 ` 112 p
33 ! 49 1 65 A 81 Q 97 a 113 q
34 " 50 2 66 B 82 R 98 b 114 r
35 # 51 3 67 C 83 S 99 c 115 s
36 $ 52 4 68 D 84 T 100 d 116 t
37 % 53 5 69 E 85 U 101 e 117 u
38 & 54 6 70 F 86 V 102 f 118 v
39 ' 55 7 71 G 87 W 103 g 119 w
40 ( 56 8 72 H 88 X 104 h 120 x
41 ) 57 9 73 I 89 Y 105 i 121 y
42 * 58 : 74 J 90 Z 106 j 122 z
43 + 59 ; 75 K 91 [ 107 k 123 {
44 , 60 < 76 L 92 \ 108 l 124 |
45 - 61 = 77 M 93 ] 109 m 125 }
46 . 62 > 78 N 94 ^ 110 n 126 ~
47 / 63 ? 79 O 95 _ 111 o

So if we wanted to shift "A" by three spaces, we first convert it to a number (65). Then we add 3 to 65, to get 68. Then we convert the number 68 back to a letter ("D"). We will use the chr() and ord() functions to convert between letters and numbers.

For example, the letter "A" is represented by the number 65. The letter "m" is represented by the number 109. A table of all the ASCII characters from 32 to 12 is in Table 14.1.

The chr() and ord() Functions

The chr() function (pronounced "char", short for "character") takes an integer ASCII number for the parameter and returns the single-character string. The ord() function (short for "ordinal") takes a single-character string for the parameter, and returns the integer ASCII value for that character. Try typing the following into the interactive shell:

>>> chr(65)
'A'
>>> ord('A')
65
>>> chr(65+8)
'I'
>>> chr(52)
'4'
>>> chr(ord('F'))
'F'
>>> ord(chr(68))
68
>>>

On the third line, chr(65+8) evaluates to chr(73). If you look at the ASCII table, you can see that 73 is the ordinal for the capital letter "I". On the fifth line, chr(ord ('F')) evaluates to chr(70) which evaluates to 'F'. Feeding the result of ord() to chr() will give you back the original argument. The same goes for feeding the result of chr() to ord(), as shown by the sixth line.

Using chr() and ord() will come in handy for our Caesar Cipher program. They are also helpful when we need to convert strings to numbers and numbers to strings.

Sample Run of Caesar Cipher

Here is a sample run of the Caesar Cipher program, encrypting a message:

Do you wish to encrypt or decrypt a message?
encrypt
Enter your message:
The sky above the port was the color of television, tuned to a dead channel.
Enter the key number (1-26)
13
Your translated text is:
Gur fxl nobir gur cbeg jnf gur pbybe bs gryrivfvba, gharq gb n qrnq punaary.

Now we will run the program and decrypt the text that we just encrypted.

Do you wish to encrypt or decrypt a message?
decrypt
Enter your message:
Gur fxl nobir gur cbeg jnf gur pbybe bs gryrivfvba, gharq gb n qrnq punaary.
Enter the key number (1-26)
13
Your translated text is:
The sky above the port was the color of television, tuned to a
dead channel.

On this run we will try to decrypt the text that was encrypted, but we will use the wrong key. Remember that if you do not know the correct key, the decrypted text will just be garbage data.

Do you wish to encrypt or decrypt a message?
decrypt
Enter your message:
Gur fxl nobir gur cbeg jnf gur pbybe bs gryrivfvba, gharq gb n qrnq punaary.
Enter the key number (1-26)
15
Your translated text is:
Rfc qiw yzmtc rfc nmpr uyq rfc amjmp md rcjctgqgml, rslcb rm y
bcyb afyllcj.

Caesar Cipher's Source Code

Here is the source code for the Caesar Cipher program. If you don't want to type all of this code in, you can visit this book's website at the URL http://inventwithpython.com/chapter14 and follow the instructions to download the source code. After you type this code in, save the file as cipher.py

cipher.py

This code can be downloaded from http://inventwithpython.com/cipher.py

If you get errors after typing this code in, compare it to the book's code with the online

diff tool at http://inventwithpython.com/diff or email the author at

al@inventwithpython.com

1.   # Caesar Cipher 
2.
3.   MAX_KEY_SIZE = 26 
4.
5. def getMode() :
6.     while True:
7.         print('Do you wish to encrypt or decrypt a message?')
8.         mode = input().lower()
9.          if mode in 'encrypt e decrypt d'.split():
10.             return mode
11.         else:
12.             print('Enter either "encrypt" or "e" or "decrypt" or "d".')
13.
14. def getMessage() :
15.     print('Enter your message:')
16.     return input () 
17.
18. def getKey() :
19.     key = 0
20.     while True:
21.         print('Enter the key number (1-%s)' %(MAX_KEY_SIZE))
22.         key = int(input())
23.          if (key >= 1 and key <= MAX_KEY_SIZE):
24.                             return key
25.
26. def getTranslatedMessage(mode, message, key):
27.      if mode[0] = = 'd' :
28.         key = -key
29.     translated = '' 
30.
31.      for symbol in message:
32.          if symbol.isalpha():
33.             num = ord(symbol)
34.             num += key 35 .
36.              if symbol.isupper():
37.                  if num > ord('Z'):
38.                     num -= 26
39.                  elif num < ord('A') :
40.                     num += 26
41.             elif symbol.islower():
42.                  if num > ord('z'):
43.                     num -= 26
44.                 elif num < ord('a'):
45.                     num += 26 
46.
47.                             translated += chr(num)
48.                         else:
49.                                    translated += symbol
50.               return translated
51.
52. mode = getMode()
53. message = getMessage()
54. key = getKey()
55.
56. print('Your translated text is:')
57. print(getTranslatedMessage(mode, message, key))
< Лекция 13 || Лекция 14: 12 || Лекция 15 >
Марат Хасьянов
Марат Хасьянов
Россия
Роман Дрындик
Роман Дрындик
Россия