0.0
No commit activity in last 3 years
No release in over 3 years
Implementation of Caesar and Vigenere ciphers
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.1
~> 0.13
~> 3.9
 Project Readme

Shift Ciphers Gem Version Build Status

Shift Ciphers gem is simple, yet complete, implementation of classic Caesar and Vigenère ciphers. It also features custom, hardened version of Vigenère cipher, which uses autokey scheme and PRNGs.

Installation

gem install shift_ciphers

Basic usage

require 'shift_ciphers'

plaintext = "Attack at dawn!"

encrypted = ShiftCiphers::Caesar.encrypt(plaintext, offset: 5)    # => "Fyyfhp%fy%ifBs^"
decrypted = ShiftCiphers::Caesar.decrypt(encrypted, offset: 5)    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

encrypted = ShiftCiphers::Vigenere.encrypt(plaintext, "my keyword")    # => "W!0uqS3yU=zI3H{"
decrypted = ShiftCiphers::Vigenere.decrypt(encrypted, "my keyword")    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

encrypted = ShiftCiphers::HardenedVigenere.encrypt(plaintext, "my keyword")    # => "$Uj:o 2M9S+<Cq9"
decrypted = ShiftCiphers::HardenedVigenere.decrypt(encrypted, "my keyword")    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

... or instantiate a cipher, and benefit from stored configuration info (e.g. offset for Caesar cipher, or key for Vigenère):

caesar = ShiftCiphers::Caesar.new
caesar.offset = 5
encrypted = caesar.encrypt(plaintext)    # => "Fyyfhp%fy%ifBs^"
decrypted = caesar.decrypt(encrypted)    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

vigenere = ShiftCiphers::Vigenere.new("my keyword")
encrypted = vigenere.encrypt(plaintext)    # => "W!0uqS3yU=zI3H{"
decrypted = vigenere.decrypt(encrypted)    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

strong_vigenere = ShiftCiphers::HardenedVigenere.new("my keyword")
encrypted = strong_vigenere.encrypt(plaintext)    # => "$Uj:o 2M9S+<Cq9"
decrypted = strong_vigenere.decrypt(encrypted)    # => "Attack at dawn!"
decrypted == plaintext  # Should be true

You can customize alphabet used by cipher:

plaintext = "ATTACKATDAWN"
encrypted = ShiftCiphers::Vigenere.encrypt(plaintext, "KEYWORD", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ")    # => "KXRWQBDDHYSB"
decrypted = ShiftCiphers::Vigenere.decrypt(encrypted, "KEYWORD", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ")    # => "ATTACKATDAWN"
decrypted == plaintext  # Should be true

When you attempt to encrypt a string, which contains character that is not in the cipher's alphabet, then ShiftCiphers::CipherError is rised:

plaintext = "ATTACK!"
encrypted = ShiftCiphers::Vigenere.encrypt(plaintext, "KEYWORD", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
# Raises ShiftCiphers::CipherError: Invalid input "ATTACK!". Character "!" is not in the alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

You can avoid this exception by telling cipher not to encrypt characters which are not in its alphabet. This is done by passing nonalphabet_char_strategy argument to encrypt/decrypt class method (or by using nonalphabet_char_strategy= instance method):

plaintext = "ATTACK AT DAWN!"
encrypted = ShiftCiphers::Vigenere.encrypt(plaintext, "KEYWORD", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", nonalphabet_char_strategy: :dont_encrypt)
decrypted = ShiftCiphers::Vigenere.decrypt(encrypted, "KEYWORD", alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", nonalphabet_char_strategy: :dont_encrypt)
puts plaintext  # => ATTACK AT DAWN!
puts encrypted  # => KXRWQB DD HYSB!
decrypted == plaintext  # Should be true