Base64 Encoding in Elixir

Here’s the translation of the Base64 Encoding example from Go to Elixir, formatted in Markdown suitable for Hugo:

defmodule Base64Example do
  def run do
    # Here's the string we'll encode/decode.
    data = "abc123!?$*&()'-=@~"

    # Elixir provides built-in support for base64 encoding/decoding.
    # Here's how to encode using the standard encoder.
    s_enc = Base.encode64(data)
    IO.puts(s_enc)

    # Decoding may return an error, which you can handle with pattern matching.
    {:ok, s_dec} = Base.decode64(s_enc)
    IO.puts(s_dec)
    IO.puts("")

    # This encodes/decodes using a URL-compatible base64 format.
    u_enc = Base.url_encode64(data)
    IO.puts(u_enc)
    {:ok, u_dec} = Base.url_decode64(u_enc)
    IO.puts(u_dec)
  end
end

Base64Example.run()

Elixir provides built-in support for base64 encoding/decoding.

In Elixir, we use the Base module for base64 encoding and decoding. This module is part of Elixir’s standard library, so we don’t need to import it explicitly.

We define a module Base64Example with a run function that demonstrates the encoding and decoding process.

The Base.encode64/1 function is used for standard base64 encoding. It takes a binary (which in Elixir, strings are stored as binaries) and returns the encoded string.

For decoding, we use Base.decode64/1. This function returns a tuple {:ok, decoded_string} if the decoding is successful, or {:error, :invalid_base64} if it fails. We use pattern matching to handle the successful case.

Elixir also provides URL-safe base64 encoding and decoding with Base.url_encode64/1 and Base.url_decode64/1 respectively.

When you run this program, you’ll see output similar to this:

$ elixir base64_encoding.exs
YWJjMTIzIT8kKiYoKSctPUB+
abc123!?$*&()'-=@~

YWJjMTIzIT8kKiYoKSctPUB-
abc123!?$*&()'-=@~

The string encodes to slightly different values with the standard and URL base64 encoders (trailing + vs -) but they both decode to the original string as desired.

In Elixir, error handling is typically done through pattern matching and the use of {:ok, result} and {:error, reason} tuples. This is different from many other languages that use exception handling for such cases.