The bifid cipher is one of the classical cipher techniques that can also easily be executed by hand. The technique was invented around 1901 by amateur cryptographer Felix Delastelle. The cipher is a combination of substitution and fractionizing. A square $$n \times n$$ grid ($$2 \leq n \leq 10$$) is used. In this grid you will find all symbols that occur in the text that needs ciphering. In order to further explain this technique we will use the $$9 \times 9$$ grid below as an example. Pay attention to the fact that a space occurs as a symbol on the sixth row and the eighth column (rows and columns are numbered from zero).
In order to cipher the original text This is a dead parrot!, every symbol of the text is converted to the corresponding row and column number where the symbol can be found. For example, we find uppercase letter T in the grid on row 2 and column 1. These row and column numbers are written vertically under the corresponding symbols from the original text.
original text: T h i s i s a d e a d p a r r o t ! ------------------------------------------- row: 2 4 4 6 6 4 6 6 4 6 4 4 4 4 6 5 4 5 5 5 6 7 column: 1 7 8 0 8 8 0 8 0 8 3 4 0 3 8 6 0 8 8 5 1 5
After that, the digits are written after each other: first the row numbers, followed by the column numbers.
2 4 4 6 6 4 6 6 ... 5 5 6 7 1 7 8 0 ... 8 6 0 8 8 5 1 5
At last, the digits are put together in groups of two, and every pair of digits is converted to the corresponding symbol in the square grid. The first digit of every pair represents the row number in the grid, the second represents the column number. The pair 2|4, for example, corresponds with the uppercase letter W, that we can find in the grid on row 2 and column 4.
2|4 4|6 6|4 6|6 ... 5|5 6|7 1|7 8|0 ... 8|6 0|8 8|5 1|5 W g w y o z Q ( $ I } O
Here we see how the original text This is a dead parrot! was converted according to the bifid cipher in the coded text WgwygeexfozQ(%II5D$I}O. In order the decipher the text, we should apply the reverse process.
Define a class Bifid that can be used to code an decode texts using the bifid cipher with a given square grid. This class must support the following methods:
An initializing method __init__ that allows making a bifid cipher for a given square $$n \times n$$ grid. Two arguments must be given to this method: the value $$n$$ and a string with length $$n^2$$ with the symbols of the grid, printed from left to right and from top to bottom. The initializing method should verify $$2 \leq n \leq 10$$ and that the string given has the correct length. Look at the example below to determine which action the method should take if the conditions aren't met.
A method symbol that prints the symbol that can be found in the grid on a given row and a given column. The row and column number must be given to the method as separate arguments. Look at the example below to see which action the method should take if the position given in invalid.
A method position that prints a tuple with the row number and the column number of the position in the grid on which a given symbol can be found. The symbol must be given as an argument to the method. Look at the example below to determine which action the method should take if the symbol does not consist of only one character, or if the symbol can't be found in the grid.
A method code that prints the coded version of a given text as a result. The text must be coded according to the bifid cipher with the grid that was given when making the Bifid object. The original text must be given to the function as an argument.
A method decode that prints the original version of a ciphered text as a result. The text must be decoded according to the bifid cipher with the grid that was given when making the Bifid object. The coded text must be given to the function as an argument.
Remark: If you use the test examples below for a docstring, you should know that a single quotation mark that is used in the string that was given as second argument to the initializing method of the class Bifid, must get a double escape. In other words, the fragment \' in the string must be replaced by \\'.
>>> cipher = Bifid(9, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdef' \
+ 'ghijklmnopqrstuvwxyz .,;:?!"\'-()[]{}$=%')
>>> cipher.symbol(2, 1)
'T'
>>> cipher.symbol(7, 10)
Traceback (most recent call last):
AssertionError: invalid position in grid
>>> cipher.position('T')
(2, 1)
>>> cipher.position('WRONG')
Traceback (most recent call last):
AssertionError: symbol must consist of 1 character
>>> cipher.position('~')
Traceback (most recent call last):
AssertionError: unknown symbol: '~'
>>> cioher.code('This is a dead parrot!')
'WgwygeexfozQ(%II5D$I}O'
>>> cipher.decode('WgwygeexfozQ(%II5D$I}O')
'This is a dead parrot!'
>>> cipher = Bifid(20, '...')
Traceback (most recent call last):
AssertionError: 2 <= n <= 10 must apply
>>> cipher = Bifid(3, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
Traceback (most recent call last):
AssertionError: number of symbols does not correspond to size grid