Bifid Cipher

Introduction

The Bifid cipher is one of several ciphers invented around the turn of the 20th century by Fench amateur cryptographer Félix Delastelle. It is based around the use of a Polybius square along with some transposition.

Example

First, draw up a Polybius square. The following one leaves out the letter 'J'. All 'J's will be rounded down to the letter 'I' in our message.

 12345
1MXTSV
2GWBCF
3NDRZL
4OYQAP
5IHKUE

To encode the message, 'THE SECRET IS OUT', we work out the coordinates of each character in our Polybius square.

 THESECRETISOUT
Row15515235151451
Column32545435314143

We encode the message into cipher text by reading pairs of co-ordinates horizontally from our grid (in rows) rather than vertically, as we laid them out. If we do that as one long string, we get,

1, 5, 5, 1, 5, 2, 3, 5, 1, 5, 1, 4, 5, 1,3, 2, 5, 4, 5, 4, 3, 5, 3, 1, 4, 1, 4, 3

From this, we can read out a new set of co-ordinate pairs and use our Polybius square to encode them as letters,

1, 5V
5, 1I
5, 2H
3, 5L
1,5V
1, 4S
5, 1I
3, 2D
5, 4U
5, 4U
3, 5L
3, 1N
4, 1O
4, 3Q

This gives a final cipher text of,

VIHLVSIDUULNOQ

Programming The Cipher

This is another one of those ciphers where the by-hand process is more straightforward than writing the programming logic. It is also the type of cipher that can be implemented with a wide range of different data structures. The pseudocode in this section will use a single string to store the Polybius square using the techniques described in the Tap Code page.

The plain text is already cleaned up in this example. An explanation of how to do this is covered in the page on the Vignère page.

Encryption

plain ← "THESECRETISOUT"
cipherAlphabet ← "MXTSVGWBCFNDRZLOYQAPIHKUE"
DECLARE INTEGER new_places[plain.LENGTH * 2 - 1]
position ← 0
FOR i ← 0 TO plain.LENGTH - 1
   position ← cipherAlphabet.INDEXOF(plain(i))
   new_places[i] ← position DIV 5 + 1
   new_places[i + plain.LENGTH] ← position MOD 5 + 1
END FOR
cipher ← ""
counter ← 0
FOR i ← 0 TO plain.LENGTH - 1
   cipher ← cipher + cipherAlphabet(((new_places[counter] - 1) * 5) + new_places[counter + 1] - 1)
   counter ← counter + 2
END FOR
OUTPUT cipher

We use an array of integers to store the co-ordinates. You can create two arrays, one for rows, one for columns. It is a shorter solution if you place the co-ordinates usefully as you work them out.

Decryption

As with the algorithm for encryption, the trick is in how you build and output the array of co-ordinate values.

cipherAlphabet ← "MXTSVGWBCFNDRZLOYQAPIHKUE"
cipher ← "VIHLVSIDUULNOQ"
DECLARE INTEGER new_places[plain.LENGTH * 2 - 1]
counter ← 0
FOR i ← 0 TO cipher.LENGTH - 1
   position ← cipherAlphabet.INDEXOF(plain(i))
   new_places[counter] ← position DIV 5 + 1
   new_places[counter + 1] ← position MOD 5 + 1
   counter ← counter + 2
END FOR
out ← ""
FOR i ← 0 TO cipher.LENGTH - 1
   out ← out + cipherAlphabet(((new_places[counter] - 1) * 5) + new_places[counter + cipher.LENGTH] - 1)
END FOR
OUTPUT OUT

Challenges

Once you have implemented this, you should recall that the letter 'J' was left out of our Polybius square. You will need a method for 'rounding' these letters to make them 'I'. Simply replacing them in the original string would do.

Generating a Polybius square at random and turning it into a cipher alphabet would be a useful addition. For variety, a keyword based square could be made following whatever filling method you choose.

Why not explore the impact of doing multiple encryptions on some text? A program could do this for you quickly.