I must implement a simple Caesar cipher class. Initializer takes two parameters - number of positions to shift the alphabet (integer) and the alphabet used (as string, not necessarily the standard English alphabet). The class must have two instance methods encrypt
and decrypt
, which take a string and do the respective action based on the parameters of the initializer. These are my rspec tests:
describe "Caesar" do
latin_encrypter = Caesar.new 4
dna_encrypter = Caesar.new 3, 'ACTG'
it 'encrypts correctly' do
expect(latin_encrypter.encrypt 'hello').to eq "lipps"
end
it 'encrypts correctly using DNA alphabet' do
expect(dna_encrypter.encrypt 'ACCTGA').to eq "GAACTG"
end
it 'decrypts correctly' do
expect(latin_encrypter.decrypt 'lipps').to eq 'hello'
end
it 'decrypts correctly using DNA alphabet' do
expect(dna_encrypter.decrypt 'GAACTG').to eq 'ACCTGA'
end
end
and this is my implementation:
class Caesar
def initialize(shift, alphabet = 'abcdefghijklmnopqrstuvwxyz')
@shift = shift % alphabet.size
@alphabet = alphabet
end
def encrypt(string)
string.chars.map { |char| @alphabet[@alphabet.index(char) + @shift - @alphabet.size] }.join
end
def decrypt(string)
string.chars.map { |char| @alphabet[@alphabet.index(char) - @shift] }.join
end
end
Is this an optimal algorithm for encryption/decryption or is there a better one (perhaps using gsub
)?
Caesar.new(1).encrypt('1337')
→NoMethodError: undefined method `+' for nil:NilClass
. The parameter may be invalid, but the error message should be more helpful. \$\endgroup\$ – 200_success Nov 13 '13 at 23:18