Current section
Files
Jump to
Current section
Files
lib/codex/base/base64.ex
defmodule Codex.Base.Base64 do
import Codex
@capitals 65..90 |> Enum.map(&:binary.encode_unsigned/1)
@lowers 97..122 |> Enum.map(&:binary.encode_unsigned/1)
@numbers 48..57 |> Enum.map(&:binary.encode_unsigned/1)
@char_list (@capitals ++ @lowers ++ @numbers ++ ["+", "/"]) |> Enum.with_index()
@char_to_num @char_list |> Enum.into(%{})
@num_to_char @char_list |> Enum.map(fn {char, num} -> {num, char} end) |> Enum.into(%{})
@spec codec() :: Codex.codec(String.t())
def codec() do
char_2 = bits(2) |> done() |> pad(4) |> index_to_char()
char_4 = bits(4) |> done() |> pad(2) |> index_to_char()
list(
choice(
[
char(4),
char(1) ++ [char_2] ++ padding(2),
char(2) ++ [char_4] ++ padding(1)
]
|> Enum.map(&(&1 |> sequence() |> join()))
)
)
|> join(4)
end
defp padding(count), do: List.duplicate(value("="), count)
defp char(count), do: List.duplicate(bits(6) |> index_to_char(), count)
defp index_to_char(index),
do: convert(index, &Map.fetch!(@num_to_char, &1), &Map.fetch!(@char_to_num, &1))
end