호두나무 공방/Exercism in Elixir

Simple Cipher - Exercism in Elixir

2022. 9. 21. 22:49

문제 보기

카이사르 암호 식의 기본적인 암호를 구현하는 문제였다. 차이라면 문자 사이가 일정하게 주어지는 것이 아니라 문자마다 거리를 지정할 수 있도록 일종의 암호화 키(key)가 주어진다는 점. 문자 리스트로 바꿔서 편하게 풀 수 있었다.

defmodule SimpleCipher do
  def encode(plaintext, key) do
    extended_key = extend_key(key, String.length(plaintext))

    Enum.zip(String.to_charlist(plaintext), extended_key)
    |> Enum.map(fn {ch, k} ->
      encoded = ch + k
      if encoded > ?z, do: encoded - 26, else: encoded
    end)
    |> to_string()
  end

  def decode(ciphertext, key) do
    extended_key = extend_key(key, String.length(ciphertext))

    Enum.zip(String.to_charlist(ciphertext), extended_key)
    |> Enum.map(fn {ch, k} ->
      decoded = ch - k
      if decoded < ?a, do: decoded + 26, else: decoded
    end)
    |> to_string()
  end

  defp extend_key(key, length) do
    key
    |> String.to_charlist()
    |> Enum.map(fn c -> c - ?a end)
    |> Stream.cycle()
    |> Enum.take(length)
  end

  def generate_key(length) do
    1..length
    |> Enum.map(fn _ -> Enum.random(?a..?z) end)
    |> to_string()
  end
end