1
\$\begingroup\$

(Here's a REPL if you want to test it online: https://repl.it/repls/RecentMonstrousOffice)

I tried to implement the Atbash cipher in Ruby and this is my final code:

# frozen_string_literal: true

module Cryptorb
  # The Atbash cipher 
  module Atbash
    module_function

    # Encrypts a string
    #
    # @param plaintext [String] the message that will be encrypted
    #
    # @return [String] the encrypted message
    def encrypt(plaintext:)
      atbash(plaintext)
    end

    # Decrypts an encrypted string
    #
    # @param ciphertext [String] the encrypted message that will be decrypted
    #
    # @return [String] the decrypted message
    def decrypt(ciphertext:)
      atbash(ciphertext)
    end

    # The algorithm
    def atbash(string)
      cap_a, cap_z = 65, 90
      a, z = 97, 122

      ciphertext = string.chars.map do |char|
        limits = [cap_a, cap_z] if char.ord.between?(cap_a, cap_z)
        limits = [a, z] if char.ord.between?(a, z)

        limits ? (limits.last - (char.ord - limits.first)).chr : char
      end

      ciphertext.join
    end

    private_class_method :atbash
  end
end

Characters that are not letters (spaces, numbers...) and letter case (uppercase and lowercase) should not be modified. Example: "1" should map to "1", "." should map to ".", "B" should map to "Y", "b" should map to "y"...

Note that this algorithm does not follow the "official" mathematical function of the Atbash cipher (E(x) = (-x mod m) + 1). Do you think it would be better if it did?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.