Engee documentation
Notebook

Bifid code

This example implements encryption and decryption using Polybius Square, a classical encryption method that has been used since ancient Greece. Polybius Square is a table in which each letter of the alphabet is mapped to coordinates (row and column). In this code, the Polybius Square is created dynamically based on a given key and then used to encrypt and decrypt messages.

Description

The Bifid cypher is. is a polygraphic substitution cipher that was invented Felix Delastell around 1901. In order to encrypt message, it uses a Polybius square of size 5 х 5 in combination with transposition and fractionation. Any Polybius square of size 5 х 5, but, since it has only 25 cells and 26 letters of the (English) alphabet, one cell must represent two letters, I and J, which is the usual choice.

Function polybius(text)

This function creates a Polybius square based on the passed text (key).

In [ ]:
polybius(text) = Char.(reshape(Int.(collect(text)), isqrt(length(text)), :)')
Out[0]:
polybius (generic function with 1 method)
  • collect(text) converts the string text into an array of characters.
  • Int.(...) converts each character into its numeric representation (ASCII code).
  • reshape(...) converts an array of numbers into a square matrix. The dimensionality of the matrix is defined as the square root of the length of the of the text (isqrt(length(text))).
  • Char.(...) converts numbers back to characters.

Function encrypt(message, poly)

This function encrypts a message using Polybius square.

In [ ]:
function encrypt(message, poly)
    positions = [findall(==(c), poly)[1] for c in message]
    numbers = vcat([c[1] for c in positions], [c[2] for c in positions])
    return String([poly[numbers[i], numbers[i+1]] for i in 1:2:length(numbers)-1])
end
Out[0]:
encrypt (generic function with 1 method)
  • For each character in the message, (message) finds its coordinates (row and column) in the Polybius square using the findall(==(c), poly).
  • The coordinates are combined into a single array of numbers (numbers), where all row numbers come first, followed by all column numbers.
  • The numbers are grouped in pairs, and for each pair is found the the corresponding symbol in the Polybius square.
  • The result is returned as an encrypted string.

Function decrypt(message, poly)

This function decrypts a message encrypted using the square of the Polybius.

In [ ]:
function decrypt(message, poly)
    n = length(message)
    positions = [findall(==(c), poly)[1] for c in message]
    numbers = reduce(vcat, [[c[1], c[2]] for c in positions])
    return String([poly[numbers[i], numbers[i+n]] for i in 1:n])
 end
Out[0]:
decrypt (generic function with 1 method)
  • For each character in the encrypted message, it finds its coordinates in the Polybius square.

  • The coordinates are combined into one array of numbers (numbers).

  • The numbers are grouped in pairs, and for each pair. the corresponding symbol in the Polybius square.

  • The result is returned as a decoded string.

Main loop

The loop checks various combinations of keys and messages:

  • Key: "ABCDEFGHIKLMNOPQRSTUVWXYZ", message: "ILOVEENGEE".

  • Key: "BGWKZQPNDSIOAXEFCLUMTHYVR", message: "EXPONENTA".

  • Key: extended alphabet (including spaces, numbers and symbols), message: "Engee is the best environment for model based developement."

In [ ]:
for (key, text) in [("ABCDEFGHIKLMNOPQRSTUVWXYZ", "ILOVEENGEE"), ("BGWKZQPNDSIOAXEFCLUMTHYVR", "EXPONENTA"),
   ([' '; '.'; 'A':'Z'; 'a':'z'; '0':'9'], "Engee is the best environment for model based design.")]

    poly = polybius(key)
    encrypted = encrypt(text, poly)
    decrypted = decrypt(encrypted, poly)
    
    println("Using polybius:")
    display(poly)

    println("\n    Сообщение: $text\n   
    Зашифрованное: $encrypted\n
    Дешифрованное: $decrypted\n\n")
end
Using polybius:
5×5 Matrix{Char}:
 'A'  'B'  'C'  'D'  'E'
 'F'  'G'  'H'  'I'  'K'
 'L'  'M'  'N'  'O'  'P'
 'Q'  'R'  'S'  'T'  'U'
 'V'  'W'  'X'  'Y'  'Z'
    Сообщение: ILOVEENGEE
   
    Зашифрованное: HPAMAQQZMZ

    Дешифрованное: ILOVEENGEE


Using polybius:
5×5 Matrix{Char}:
 'B'  'G'  'W'  'K'  'Z'
 'Q'  'P'  'N'  'D'  'S'
 'I'  'O'  'A'  'X'  'E'
 'F'  'C'  'L'  'U'  'M'
 'T'  'H'  'Y'  'V'  'R'
    Сообщение: EXPONENTA
   
    Зашифрованное: ANNSECNYW

    Дешифрованное: EXPONENTA


Using polybius:
8×8 Matrix{Char}:
 ' '  '.'  'A'  'B'  'C'  'D'  'E'  'F'
 'G'  'H'  'I'  'J'  'K'  'L'  'M'  'N'
 'O'  'P'  'Q'  'R'  'S'  'T'  'U'  'V'
 'W'  'X'  'Y'  'Z'  'a'  'b'  'c'  'd'
 'e'  'f'  'g'  'h'  'i'  'j'  'k'  'l'
 'm'  'n'  'o'  'p'  'q'  'r'  's'  't'
 'u'  'v'  'w'  'x'  'y'  'z'  '0'  '1'
 '2'  '3'  '4'  '5'  '6'  '7'  '8'  '9'
    Сообщение: Engee is the best environment for model based design.
   
    Зашифрованное: DiejDiBjmjyrrjmjmraeZqWaqjEI Cu5 m1 HjP N.T VFDkFFEgH

    Дешифрованное: Engee is the best environment for model based design.


Conclusion

This example demonstrates how Polybius Square can be used to encrypt and decrypt messages, and how to adapt it to work with different alphabets and symbols.