Playfair cipher

You are encouraged to solve this task according to the task description, using any language you may know.
Task

Implement a  Playfair cipher for encryption and decryption.



The user must be able to choose   J  =  I     or   no   Q   in the alphabet.

The output of the encrypted and decrypted message must be in capitalized digraphs, separated by spaces.



Output example

                HI DE TH EG OL DI NT HE TR EX ES TU MP



import pegs, strutils
 
type
  Position = tuple[x, y: int]
  Playfair = object
    positions: array['A'..'Z', Position]
    table: array[5, array[5, char]]
 
const None: Position = (-1, -1)   # Default value for positions.
 
 
proc initPlayfair(key: string; jti: bool): Playfair =
 
  for item in result.positions.mitems: item = None
 
  var alphabet = key & "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  alphabet = if jti: alphabet.replace('J', 'I')
             else: alphabet.replace("Q", "")
 
  var k = 0
  for ch in alphabet:
    if result.positions[ch] == None:
      result.table[k div 5][k mod 5] = ch
      result.positions[ch] = (k mod 5, k div 5)
      inc k
 
 
proc codec(playfair: Playfair; text: string; direction: int): string =
 
  result.setLen(text.len)
 
  for i in countup(0, text.high, 2):
    var
      (col1, row1) = playfair.positions[text[i]]
      (col2, row2) = playfair.positions[text[i + 1]]
 
    if row1 == row2:
      col1 = (col1 + direction) mod 5
      col2 = (col2 + direction) mod 5
    elif col1 == col2:
      row1 = (row1 + direction) mod 5
      row2 = (row2 + direction) mod 5
    else:
      swap col1, col2
 
    result[i] = playfair.table[row1][col1]
    result[i + 1] = playfair.table[row2][col2]
 
 
proc encode(playfair: Playfair; text: string): string =
  var
    text = text
    i = 0
 
  while i < text.len:
    if i == text.high:
      if (text.len and 1) != 0:
        text.add 'X'
    elif text[i] == text[i + 1]:
      text.insert("X", i + 1)
    inc i, 2
 
  result = playfair.codec(text, 1)
 
 
proc decode(playfair: Playfair; text: string): string =
  result = playfair.codec(text, 4)
 
 
proc prompt(msg: string): string =
  stdout.write msg
  try:
    result = stdin.readLine()
  except EOFError:
    echo ""
    quit getCurrentExceptionMsg(), QuitFailure
 
 
when isMainModule:
 
  var key: string
  while key.len <= 6:
    key = prompt("Enter an encryption key (min letters 6): ").toUpperAscii().replace(peg"[^A-Z]")
 
  var text: string
  while text.len == 0:
    text = prompt("Enter the message: ").toUpperAscii().replace(peg"[^A-Z]")
 
  var answer: string
  while answer notin ["y", "n"]:
    answer = prompt("Replace J with I? y/n: ").toLowerAscii()
  let jti = (answer == "y")
 
  let playfair = initPlayfair(key, jti)
  let enc = playfair.encode(text)
  let dec = playfair.decode(enc)
 
  echo "Encoded message: ", enc
  echo "Decoded message: ", dec