📜  Playfair密码范例(1)

📅  最后修改于: 2023-12-03 15:03:47.303000             🧑  作者: Mango

Playfair Cipher

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.

How it works

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:

  1. If two letters are the same, we insert an "X" between them.
  2. We find the position of each letter in the grid, and then encrypt them using the following rules:
    • If the letters are in the same row, we replace each letter with the letter to its right (wrapping around if needed).
    • If the letters are in the same column, we replace each letter with the letter below it (wrapping around if needed).
    • If the letters are not in the same row or column, we form a rectangle with them and replace each letter with the letter at the opposite corner of the rectangle.

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".

Code example

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