defmodule Atbash do @letters ?a..?z |> Enum.to_list |> to_string |> String.graphemes() @digits ?0..?9 |> Enum.to_list |> to_string |> String.graphemes() @table Map.new(Enum.zip(@letters, Enum.reverse(@letters))) defguardp is_letter(char) when char in @letters defguardp is_digit(char) when char in @digits @doc """ Encode a given plaintext to the corresponding ciphertext ## Examples iex> Atbash.encode("completely insecure") "xlnko vgvob rmhvx fiv" """ @spec encode(String.t()) :: String.t() def encode(plaintext) do plaintext |> transpose() |> String.graphemes() |> Enum.chunk_every(5) |> Enum.join(" ") end @spec decode(String.t()) :: String.t() def decode(cipher), do: transpose(cipher) defp transpose(string) do string |> String.downcase() |> String.graphemes() |> Enum.map(&code/1) |> Enum.join() end defp code(char) when is_digit(char), do: char defp code(char) when is_letter(char), do: @table[char] defp code(_char), do: nil end