Mar 14, 2025 | 1535 words | 15 min read
12.1.1. Materials#
Encrypting Text with Ciphers#
Encryption is the process of converting plaintext into ciphertext to secure the information. Ciphers are algorithms used to perform encryption and decryption. In this project, we’ll explore three types of ciphers: Caesar, Rail Fence, and Beaufort.
Caesar Cipher#
The “Caesar Cipher” is one of the simplest and oldest encryption techniques. It is a
substitution cipher, where each character in the plaintext is shifted by a fixed
number of positions down or up the alphabet. For example, with a shift of \(3\),
A becomes D, B becomes E, and so on. The alphabet wraps around, so Z would
become C. Encrypting the plaintext message HELLO with a shift of \(3\) would
give KHOOR as the ciphertext. If a message was encrypted with a shift of \(3\),
we can decrypt it by applying the same process with a shift of \(-3\). Applying a
shift of \(-3\) to the ciphertext KHOOR would reveal the plaintext HELLO.
Numbers are shifted in the same way as letters, but they wrap around from 9 to 0.
Example#
For demonstration purposes, below is Caesar cipher example using the plaintext Hello 5! and shift of \(3\).
Shifted Character Tables (Shift of 3)#
Original Letter |
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Shifted Letter |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z |
A |
B |
C |
Original Letter |
a |
b |
c |
d |
e |
f |
g |
h |
i |
j |
k |
l |
m |
n |
o |
p |
q |
r |
s |
t |
u |
v |
w |
x |
y |
z |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Shifted Letter |
d |
e |
f |
g |
h |
i |
j |
k |
l |
m |
n |
o |
p |
q |
r |
s |
t |
u |
v |
w |
x |
y |
z |
a |
b |
c |
Original Digits |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
0 |
|---|---|---|---|---|---|---|---|---|---|---|
Shifted Digits |
4 |
5 |
6 |
7 |
8 |
9 |
0 |
1 |
2 |
3 |
Encryption Process#
Original Character |
H |
E |
L |
L |
O |
5 |
! |
|
|---|---|---|---|---|---|---|---|---|
Character Position |
7 |
4 |
11 |
11 |
14 |
- |
5 |
- |
Shifted Position |
10 |
7 |
14 |
14 |
17 |
- |
8 |
- |
Shifted Character |
K |
H |
O |
O |
R |
8 |
! |
Note
Character Position: Assign numbers to letters where A=0, B=1, …, Z=25.
Shifted Position: For letters, calculated as (Original Position + Shift) mod 26. For numbers, calculated as (Original Position + Shift) mod 10.
Shifted Character: The character corresponding to the shifted position.
Special characters, like spaces are not shifted.
Decryption Process#
Cipher Character |
K |
H |
O |
O |
R |
8 |
! |
|
|---|---|---|---|---|---|---|---|---|
Character Position |
10 |
7 |
14 |
14 |
17 |
- |
8 |
- |
Shifted Position |
7 |
4 |
11 |
11 |
14 |
- |
5 |
- |
Original Character |
H |
E |
L |
L |
O |
5 |
! |
Rail Fence Cipher#
The Rail Fence Cipher is a type of transposition cipher where each character of the plaintext is
scrambled according to some pattern, but the character values are left unchanged. It derives its
name from the manner in which encryption is performed, like a fence built with horizontal rails.
How it works:
Rail formation: Create the rails (arrays) to store characters. The integer value of the key will represent the number of rails. Note that the key must be an integer for the Rail Fence Cipher.
Rail structure: The rails must be of equal length and stacked vertically. You may need to increase the length of the rails to ensure that the plaintext begins in the top left corner and ends in either the top right or bottom right corners. For this, you may need to pad the plaintext with ‘x’s.
Encrypting:
The plaintext is written downwards diagonally on successive “rails” of an imaginary fence, then moving up when the bottom rail is reached, down again when the top rail is reached, and so on until the whole plaintext is written out.
You may need some padding of ‘x’s in order to reach a corner on the right side of your rail fence.
The ciphertext is then read off in rows, skipping any empty locations in the rails.
Decrypting:
Determine the length of rails using the length of the ciphertext. The number of rails is determined by the decryption key.
Create the rail fence structure and fill it out by calculating the pattern of letters for the particular number of rails. See the example below for further details on this step.
Example#
For demonstration purposes, below is a Rail Fence cipher example using the Plaintext Value “I love Python!” and the key “3”.
1. Create rail fence#
Since “I love Python!” has 14 characters and there are 3 rails, we’ll need to pad the plaintext with 1 ‘x’ to reach on of the right corners. Spaces are shown with an ‘_’ character in the table below.
Counts |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rail 0 |
I |
v |
y |
n |
|||||||||||
Rail 1 |
_ |
o |
e |
P |
t |
o |
! |
||||||||
Rail 2 |
l |
_ |
h |
x |
2. Extract the ciphertext#
We read the rail fence left to right per rail. You must skip the empty parts of the table.
So, our ciphertext is: “Ivyn oePto!l hx”
3. Decryption Process#
To retrieve the original plaintext given an input of “Ivyn oePto!l hx” and the same key “3”, we first create the alternating pattern for 3 rails with a length of 15.
Pattern: [0, 1, 2, 1, 0, 1, 2, 1, 0, 1, 2, 1, 0, 1, 2]
This pattern tells us how to fill out each rail. For example, Rail 0 has characters in the same locations as the zeros in the patters. We then add the ciphertext characters sequentially for each rail. Below is a breakdown of this decryption for Rail 0.
Pattern |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rail 0 |
I |
v |
y |
n |
|||||||||||
Rail 1 |
|||||||||||||||
Rail 2 |
Pattern |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rail 0 |
I |
v |
y |
n |
|||||||||||
Rail 1 |
_ |
o |
e |
P |
t |
o |
! |
||||||||
Rail 2 |
Pattern |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
1 |
0 |
1 |
2 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rail 0 |
I |
v |
y |
n |
|||||||||||
Rail 1 |
_ |
o |
e |
P |
t |
o |
! |
||||||||
Rail 2 |
l |
_ |
h |
x |
We can now read back the original message from the rail fence table using the same diagonal alternating pattern. Hence, we get “I love Python!x”.
4. Extract the plaintext#
We can now read back the original message from the rail fence table using the same diagonal alternating pattern.
Hence, we get back our original message: “I love Python!x”
Beaufort Cipher#
The Beaufort Cipher encrypts messages by shifting each letter of the plaintext by a number of positions determined by a keyword. Unlike the Caesar cipher, which uses a single shift value, the Beaufort cipher uses a sequence of shifts based on the letters of a keyword.
How it works#
Encrypting#
Prepare the keyword.
Keyword: Convert to lowercase. If the keyword is shorter than the plaintext, repeat it to match the length of the plaintext.
Assign numerical values.
Convert each letter in the plaintext and keyword to its corresponding numerical value. Use the table below to assign a numerical value to each letter and number:
Table 12.10 Numerical Values for Characters# Character
Number
a
0
b
1
c
2
d
3
e
4
f
5
g
6
h
7
i
8
j
9
k
10
l
11
m
12
n
13
o
14
p
15
q
16
r
17
s
18
t
19
u
20
v
21
w
22
x
23
y
24
z
25
0
26
1
27
2
28
3
29
4
30
5
31
6
32
7
33
8
34
9
35
Make the plaintext string lowercase before encrypting.
Calculate the ciphertext.
For each letter in the plaintext, apply the shift determined by the corresponding keyword letter:
\(\text{Ciphertext Letter Value} = (\text{Keyword Value} - \text{Plaintext Letter Value}) \mod 36\)
Note
If the subtraction of \((\text{Keyword Value} - \text{Plaintext Letter Value})\) results in a negative number, make it positive by adding 36
Also it can be noted that the mod of a negative number is equivalent to adding the divisor to the number and then applying the mod \(e.g. [-4\mod7] = [(-4 + 7)\mod7] = [3\mod7] = 3\)
Look up how the mod operator in Python works for in-depth details.
Leave non-alphabetic characters unchanged.
Convert ciphertext values back to letters or numbers.
Convert the \(\text{Ciphertext Values}\) back to characters using the same table Table 12.10.
Decrypting#
Prepare the Keyword.
Ensure keyword is in lowercase.
Assign numerical values.
As in encryption, assign numerical values to the letters and numbers.
Calculate the plaintext values using the same encryption process.
\(\text{Plaintext Letter Value} = (\text{Keyword Value} - \text{Ciphertext Letter Value}) \mod 36\)
Note
If the subtraction of \((\text{Keyword Value} - \text{Ciphertext Letter Value})\) results in a negative number, make it positive by adding 36
Also it can be noted that the mod of a negative number is equivalent to adding the divisor to the number and then applying the mod \(e.g. [-4\mod7] = [(-4 + 7)\mod7] = [3\mod7] = 3\)
Look up how the mod operator in Python works for in-depth details.
Leave non-alphabetic characters unchanged.
Convert the numerical plaintext values back to a letter or numbers.
Convert the \(\text{Plaintext Values}\) back to characters using the same table Table 12.10.
Example#
For demonstration purposes, below is Beaufort cipher example using the plaintext
Hello 123 and keyword of Key.
Encryption#
Prepare the Plaintext and Keyword#
Plaintext:
Hello 12Keyword:
KeyRepeat Key to match length of Plaintext, as shown below
Plaintext Letter |
h |
e |
l |
l |
o |
1 |
2 |
|
|---|---|---|---|---|---|---|---|---|
Keyword Letter |
k |
e |
y |
k |
e |
y |
k |
e |
Extended Keyword:
KEYKEYKE(Note that we’ve converted the plaintext and key to lowercase.)
Assign Numerical Values#
Letter |
Numeric Value |
|---|---|
a |
0 |
b |
1 |
… |
… |
h |
7 |
e |
4 |
l |
11 |
o |
14 |
k |
10 |
y |
24 |
1 |
27 |
2 |
28 |
Calculate the Ciphertext#
For each character, calculate:
\(\text{Ciphertext Letter Value} = (\text{Keyword Value} - \text{Plaintext Letter Value}) \mod 36\)
Position |
Plaintext Letter |
Plaintext Value |
Keyword Letter |
Keyword Value |
Cipher Value |
Cipher Character |
|---|---|---|---|---|---|---|
1 |
h |
7 |
k |
10 |
(10 - 7) % 36 = 3 |
d |
2 |
e |
4 |
e |
4 |
(4 - 4) % 36 = 0 |
a |
3 |
l |
11 |
y |
24 |
(24 - 11) % 36 = 13 |
n |
4 |
l |
11 |
k |
10 |
(10 - 11) % 36 = 35 |
9 |
5 |
o |
14 |
e |
4 |
(4 - 14) % 36 = 26 |
0 |
6 |
y |
24 |
||||
7 |
1 |
27 |
k |
10 |
(10 - 27) % 36 = 19 |
t |
8 |
2 |
28 |
e |
4 |
(4 - 28) % 36 = 12 |
m |
Convert Numbers Back to Letters#
Ciphertext:
dan90 tm
Decryption#
To decrypt the ciphertext dan90 tm using the same keyword Key, we reverse the
encryption process.
Prepare the Ciphertext and Keyword#
Ciphertext:
dan90 tmKeyword:
KeyRepeat the lowercase key to match length of Ciphertext:
keykeyke
Assign Numerical Values#
Using the same numerical values as before.
Calculate the Plaintext#
\(\text{Plaintext Letter Value} = (\text{Keyword Value} - \text{Ciphertext Letter Value}) \mod 36\)
Position |
Cipher Letter |
Cipher Value |
Keyword Letter |
Keyword Value |
Plaintext Value |
Plaintext Letter |
|---|---|---|---|---|---|---|
1 |
d |
3 |
k |
10 |
(10 - 3) % 36 = 7 |
h |
2 |
a |
0 |
e |
4 |
(4 - 0) % 36 = 4 |
e |
3 |
n |
13 |
y |
24 |
(24 - 13) % 36 = 11 |
l |
4 |
9 |
35 |
k |
10 |
(10 - 35) % 36 = 11 |
l |
5 |
0 |
26 |
e |
4 |
(4 - 26) % 36 = 14 |
o |
6 |
y |
24 |
||||
7 |
t |
19 |
k |
10 |
(10 - 19) % 36 = 27 |
1 |
8 |
m |
12 |
e |
4 |
(4 - 12) % 36 = 28 |
2 |
We get back our original message:
Hello 12.
In summary#
Caesar Cipher: Decryption is simply the encryption process with a negative shift.
Rail Fence Cipher: Encryption and decryption rely on the proper formation of rails.
Beaufort Cipher: Encryption and decryption use the same operation.