Last active
August 29, 2015 13:57
-
-
Save waysidekoi/9401953 to your computer and use it in GitHub Desktop.
Vigenere cipher (source: http://www.problemotd.com/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Vigenere cipher | |
The Vigenere cipher made its rounds in the mid-1550s up until the end of the American Civil War. | |
It was very easy for soldiers to encode messages and pass them around to all the allied camps. It | |
was very easy for soldiers to encode messages and pass them aroudn to all the allied camps. | |
The cipher requires a key and a message. It works like this: | |
Key: | |
Message: | |
TODAYISMYBIRTHDAY | |
REDDITREDDITREDDI | |
TODAYISMYBIRTHDAY | |
----------------- | |
KSGDGBJQBEQKKLGDG | |
Using a 0 based alphabet (A=0), R is the 17th letter of the alphabet and T is the 19th letter | |
of the alphabet. (17 + 19) mod 26 = 11 which is where K resides in the alphabet. Repeat for each | |
key/message letter combination until done. | |
Today's problem of the day is two part. The first part is to implement a Vigenere cipher in the | |
programming language of your choice. Feel free to post solutions or links to solutions in the | |
comments. | |
The second part is to try and implement something to crack the message below (the key is 5 or less | |
characters). | |
ZEJFOKHTWHCGAW | |
Good Luck! | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Part 1 | |
class Cipher | |
attr_reader :key, :msg | |
def initialize(key, msg) | |
@key = key | |
@msg = msg | |
end | |
def index_position(char) | |
alphabet = ('A'..'Z').to_a | |
alphabet.index(char) | |
end | |
def character_at(position) | |
alphabet = ('A'..'Z').to_a | |
alphabet[position] | |
end | |
def encrypt | |
result = [] | |
zipped_msg = combine | |
zipped_msg.each do |pair| | |
code_position = (index_position(pair[0]) + index_position(pair[1])) % 26 | |
result << character_at(code_position) | |
end | |
result.join | |
end | |
def combine | |
# expand key to match length of message | |
expanded_key = key * msg.length.fdiv(key.length).ceil | |
# turn key into array to pop extras | |
expanded_key = expanded_key.split(//) | |
# calc how many extra chars exist | |
key_muffintop = expanded_key.length - msg.length | |
# match message length | |
expanded_key.pop(key_muffintop) | |
# convert msg to array | |
expanded_msg = msg.split(//) | |
expanded_key.zip(expanded_msg) | |
end | |
end | |
key = 'reddit'.upcase | |
message = 'TODAYISMYBIRTHDAY'.upcase | |
cipher = Cipher.new(key, message) | |
p cipher.encrypt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment