module Vigenere

Encryption/decryption using Vigenere ciphers (en.wikipedia.org/wiki/Vigen%C3%A8re_cipher)

Public Instance Methods

build_table(key1 = alphabet.join(''), key2) click to toggle source

Public: builds the tableau needed for encryption/decryption.

Parameter(s)

key1 - String: the key found in each row. Optional; the default is a standard A-to-Z alphabet. key2 - String: the key that forms an acrostic down the left-hand side of the tableau.

Return Value

Array: a two-dimensional array of characters comprising the tableau.

Example

+build_table(‘KRYPTOS’, ‘PALIMPSEST’)+

(See EXAMPLE_VIGENERE_TABLE in krpytos.rb for the result.)

# File lib/dekryptos/vigenere.rb, line 27
def build_table(key1 = alphabet.join(''), key2)
  table = []

  key1.upcase!
  key2.upcase!

  table[0] = key1.split('')
  table[0] = populate_row(table[0], key1)
  row = table[0]

  key2.split('').each do |letter|
    table << row.rotate(row.index(letter))
  end

  table
end
decrypt(ciphertext, table, key) click to toggle source

Public: decrypts plaintext using a Vigenere cipher.

For each letter in the ciphertext, we loop through the tableau (starting at row 1) and add the corresponding character from row 0 to the plaintext string.

Parameter(s)

ciphertext - String: the text to be decrypted. table - Array: the table generated by build_table. key - String: the alphabet key that forms an acrostic down the left-hand side of the tableau (key2 in build_table).

Return Value

String: the decrypted text.

Example

+decrypt(‘DEUVRPGIJEKK’, EXAMPLE_VIGENERE_TABLE, ‘PALIMPSEST’)+ +=> “ATTACKATDAWN”+

# File lib/dekryptos/vigenere.rb, line 96
def decrypt(ciphertext, table, key)
  plaintext = ''
  key.upcase!

  ciphertext.tr('?', '').split('').each_with_index do |char, char_idx|
    table[char_idx % key.length + 1].each_with_index do |letter, letter_idx|
      plaintext << table.first[letter_idx] if letter == char
    end
  end

  plaintext
end
encrypt(plaintext, table, key) click to toggle source

Public: encrypts plaintext using a Vigenere cipher.

For each letter in the plaintext, we loop through the first row of the tableau and add the corresponding character from the row we’re currently on to the ciphertext string.

Parameter(s)

plaintext - String: the text to be encrypted. table - Array: the table generated by build_table. key - String: the alphabet key that forms an acrostic down the left-hand side of the tableau (key2 in build_table).

Return Value

String: the encrypted text.

Example

+encrypt(‘ATTACKATDAWN’, EXAMPLE_VIGENERE_TABLE, ‘PALIMPSEST’)+ +=> “DEUVRPGIJEKK”+

# File lib/dekryptos/vigenere.rb, line 63
def encrypt(plaintext, table, key)
  ciphertext = ''
  key.upcase!

  plaintext.tr('?', '').split('').each_with_index do |char, char_index|
    table.first.each_with_index do |letter, letter_index|
      ciphertext <<
        table[char_index % key.length + 1][letter_index] if letter == char
    end
  end

  ciphertext
end

Private Instance Methods

alphabet() click to toggle source

Private: generates an alphabet.

Parameter(s)

None.

Return Value

Array: an array comprising the letters of the alphabet.

# File lib/dekryptos/vigenere.rb, line 134
def alphabet
  ('A'..'Z').to_a
end
populate_row(row, key) click to toggle source

Private: builds a row in our Vigenere table.

Parameter(s)

row - Array: an array to which we add any alphabet letters, in order, that aren’t part of the key (key1 in build_table).

Return Value

Array: an array of characters constituting a row in the tableau.

# File lib/dekryptos/vigenere.rb, line 119
def populate_row(row, key)
  alphabet.each do |letter|
    row << letter unless key.include? letter
  end

  row
end