Bifid Cipher

October 13, 2009

The bifid cipher was invented by the French cryptographer Felix Delastelle in 1901. Though never used militarily, it is popular among classical cryptographers because it is simple to operate manually yet reasonably secure. Bifid uses a Polybius square to substitute a digit-pair for each plain-text letter, then transposition causes fractionation of the digit pairs, creating diffusion, and finally the transposed digits are reformed into cipher-text letters. An example is shown below:

1 2 3 4 5
1 A B C D E
2 F G H I K
3 L M N O P
4 Q R S T U
5 V W X Y Z

Our “key” is just the letters of the alphabet, in order, with J omitted; other methods of building a Polybius square have been discussed in previousexercises. To encipher a message, write the row and column numbers of the letters in two rows below the message:

So the cipher-text is OMQNHHQWUIGBIMWCS. Deciphering is the inverse operation.

Some variants of bifid break the plain-text into blocks of a given length, called the period, before encipherment, then encipher each block separately; a common period is five. A 6 × 6 variant that includes digits is also common. Another variant of bifid, called trifid, uses a 3 × 3 × 3 cube instead of a square, on the theory that if fractionating by two is good, fractionating by three is better.

Your task is to write functions that encipher and decipher messages using the bifid cipher. When you are finished, you are welcome to read or run a suggested solution, or to post your solution or discuss the exercise in the comments below.

[…] best way to learn a language is to use it to solve some non-trivial practical problems. I stumbled this problem on Programming Praxis. It’s about building a Bifid cipher, which I thought could be a […]

% makepoints({IntsList1, IntsList2}, AccumulatorList)
% Helper function for makepoints, that does most of the work
% Joins corresponding items of the two input lists to two-integer
% tuples and ads the result to accumulator list
% at the end the accumulator list is reversed to get the right order
makepoints({[], _}, Acc) -> lists:reverse(Acc);
makepoints({[X | Xlist], [Y | Ylist]}, Acc) ->
makepoints({Xlist, Ylist}, [{X, Y} | Acc]).