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\$