📅  最后修改于: 2023-12-03 15:03:47.303000             🧑  作者: Mango
The Playfair cipher is a polygraphic substitution cipher that encrypts pairs of letters instead of single letters. It was invented by Charles Wheatstone in 1854, but was named after Lord Playfair who promoted its use.
The Playfair cipher uses a 5x5 grid of letters, arranged in a square. Each letter can only appear once in the grid. The keyphrase is used to fill the grid, with the remaining letters filled in alphabetically. In the example below, we will use the keyphrase "PROGRAMMING".
| P | R | O | G | A | |:-:|:-:|:-:|:-:|:-:| | M | I | N | B | C | | D | E | F | H | K | | L | Q | S | T | U | | V | W | X | Y | Z |
To encrypt a message, we break it into pairs of letters, and then use the following rules:
Let's take the example message "HELLO WORLD". We break it into pairs: "HE", "LL", "OW", and "OR". We then encrypt each pair using the rules above to get the ciphertext "UIASLMBIPK".
Here is an implementation of the Playfair cipher in Python:
import string
def generate_grid(keyphrase):
# clean keyphrase and remove duplicate letters
keyphrase = ''.join(c.upper() for c in keyphrase if c in string.ascii_letters)
keyphrase = ''.join(sorted(set(keyphrase), key=keyphrase.index))
keyphrase += string.ascii_uppercase
keyphrase = keyphrase.replace('J', 'I')
# create 5x5 grid and fill it with letters from keyphrase
grid = []
for i in range(0, 25, 5):
row = keyphrase[i:i+5]
grid.append(row)
return grid
def encrypt(plaintext, grid):
# clean plaintext and split into pairs
plaintext = ''.join(c.upper() for c in plaintext if c in string.ascii_letters)
plaintext = plaintext.replace('J', 'I').replace(' ', '')
plaintext += 'X' * (len(plaintext) % 2)
pairs = [plaintext[i:i+2] for i in range(0, len(plaintext), 2)]
# encrypt each pair of letters
ciphertext = ''
for pair in pairs:
row1, col1 = divmod(grid.index(pair[0]), 5)
row2, col2 = divmod(grid.index(pair[1]), 5)
if row1 == row2:
ciphertext += grid[row1][(col1+1)%5] + grid[row2][(col2+1)%5]
elif col1 == col2:
ciphertext += grid[(row1+1)%5][col1] + grid[(row2+1)%5][col2]
else:
ciphertext += grid[row1][col2] + grid[row2][col1]
return ciphertext
To use this implementation, we first generate the grid from a keyphrase:
>>> grid = generate_grid('PROGRAMMING')
>>> print(grid)
[['P', 'R', 'O', 'G', 'A'], ['M', 'I', 'N', 'B', 'C'], ['D', 'E', 'F', 'H', 'K'], ['L', 'Q', 'S', 'T', 'U'], ['V', 'W', 'X', 'Y', 'Z']]
We can then encrypt a message:
>>> ciphertext = encrypt('HELLO WORLD', grid)
>>> print(ciphertext)
UIASLMBIPK