patternrubyMinor
Caesar Cipher encryptor using ASCII
Viewed 0 times
caesarencryptorasciiusingcipher
Problem
I have built a Caesar Cipher in Ruby that utilizes ASCII for the encryption. I am not sure whether or not this was the best way to go about the task but this way made the most sense to me. Please give me any feedback that comes to mind.
puts 'Please enter your string to be coded'
string = gets.chomp.split("")
puts 'Please enter your number key'
key = gets.chomp.to_i
if (key > 26)
key = key % 26
end
string.map! do |i|
i.ord
end
string.map! {|i| i = i + key}.map! {|i|
if (i > 122)
then i = i - 26
elsif (90 96 && (i - key) 64)
then i = i - 26
elsif (i 96 && i 64)
then i = i + 26
elsif (i 64)
then i = i + 26
elsif (i < 65)
then i = 32
else
i
end
}
string.map! do |i|
i.chr
end
puts string.join("")
endSolution
Your code is one block, one piece of code that goes from start to finish, mixing logic and user-interface. While it works (Great!) this is sub-optimal for readibility and maintanability.
I will now show you what I think is a more readable approach. (The concept is the same, but this code will behave a bit differently than yours. Adapting it to your needs is left as an exercise for the reader).
Without farther ado, let's start:
This code imports an automated testing framework I wrote, inatalling it is as easy as
The alphabet. Note that UPPERCASE means that it cannot be changed. It is a constant.
A short summary of what the function does, method level comments are encouraged over line level comments.
Example usage that doubles as tests, you may change them to see what happens.
This is a function, takes an input and has an output, It applies the Caesar cipher logic to a single character. The modulo operator
A short phrase of description and a pair of tests like the other function.
Here I discard the non-lowercase chars, (
And this is all, try it with:
Now user interface and logic are separated and the logic is tested. Feel free to ask any question
I will now show you what I think is a more readable approach. (The concept is the same, but this code will behave a bit differently than yours. Adapting it to your needs is left as an exercise for the reader).
Without farther ado, let's start:
require 'arrow_test'This code imports an automated testing framework I wrote, inatalling it is as easy as
gem install arrow_test in the command line. Automated tests run in milliseconds to verify the correctness of your code.ALPHABET = ("a".."z").to_aThe alphabet. Note that UPPERCASE means that it cannot be changed. It is a constant.
# Moves a letter forward in the alphabet by
# the given key wrapping around.
#A short summary of what the function does, method level comments are encouraged over line level comments.
#
# shift('a', 2) #=> 'c'
#
#
#
# shift('z', 2) #=> 'b'
# Example usage that doubles as tests, you may change them to see what happens.
def shift(letter, key)
ALPHABET[ (ALPHABET.index(letter) + key) % ALPHABET.length]
endThis is a function, takes an input and has an output, It applies the Caesar cipher logic to a single character. The modulo operator
% makes it behave like the alphabet is a circle. You may see the example with z.# Encrypts a text using by shifting all its letters by
# the given key. All characters that are not lower and alphabetic
# are deleted.
#
#
# monoalphabetic_cipher('abcd', 2) #=> 'cdef'
#
#
#
# monoalphabetic_cipher('cdef', 2, decode=true) #=> 'abcd'
# A short phrase of description and a pair of tests like the other function.
def monoalphabetic_cipher(text, key, decode=false)
text
.chars
.select { |char| ALPHABET.include?(char) }
.map {|char| shift(char, (decode ? 26 - key : key) )}
.join
endHere I discard the non-lowercase chars, (
select line), and apply the shift to each char (map line). chars and join are just to go from string to list and viceversa, not important. Seeing a 'flowchart' of the code may help understanding.And this is all, try it with:
puts 'Enter shift and then text'
shift = gets.chomp.to_i
text = gets.chomp
puts monoalphabetic_cipher(text, shift)Now user interface and logic are separated and the logic is tested. Feel free to ask any question
Code Snippets
require 'arrow_test'ALPHABET = ("a".."z").to_a# Moves a letter forward in the alphabet by
# the given key wrapping around.
## <code>
# shift('a', 2) #=> 'c'
# </code>
#
# <code>
# shift('z', 2) #=> 'b'
# </code>def shift(letter, key)
ALPHABET[ (ALPHABET.index(letter) + key) % ALPHABET.length]
endContext
StackExchange Code Review Q#101411, answer score: 4
Revisions (0)
No revisions yet.