From 3d41fa46f523765d1a92916422e8c16b694accb2 Mon Sep 17 00:00:00 2001 From: Paulo Almeida Date: Fri, 28 Mar 2014 23:10:01 +0100 Subject: [PATCH 1/2] Added option to use a lowercase alphabet in base 16 and base 32 encode and decode functions --- lib/elixir/lib/base.ex | 253 +++++++++++++++++---------- lib/elixir/test/elixir/base_test.exs | 135 ++++++++++---- 2 files changed, 258 insertions(+), 130 deletions(-) diff --git a/lib/elixir/lib/base.ex b/lib/elixir/lib/base.ex index e3a0b1e1c6a..47c6ad343b7 100644 --- a/lib/elixir/lib/base.ex +++ b/lib/elixir/lib/base.ex @@ -9,18 +9,25 @@ defmodule Base do 16 encoding schemes. """ - b16_alphabet = Enum.with_index '0123456789ABCDEF' - b64_alphabet = Enum.with_index 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - b64url_alphabet = Enum.with_index 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' - b32_alphabet = Enum.with_index 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' - b32hex_alphabet = Enum.with_index '0123456789ABCDEFGHIJKLMNOPQRSTUV' - - Enum.each [ { :enc16, :dec16, b16_alphabet }, - { :enc64, :dec64, b64_alphabet }, - { :enc32, :dec32, b32_alphabet }, - { :enc64url, :dec64url, b64url_alphabet }, - { :enc32hex, :dec32hex, b32hex_alphabet } ], fn({enc, dec, alphabet}) -> - for {encoding, value} <- alphabet do + b16_upper = '0123456789ABCDEF' + b16_lower = '0123456789abcdef' + b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + b64_url = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' + b32_upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' + b32_lower = 'abcdefghijklmnopqrstuvwxyz234567' + b32_hex_upper = '0123456789ABCDEFGHIJKLMNOPQRSTUV' + b32_hex_lower = '0123456789abcdefghijklmnopqrstuv' + + Enum.each [ { :enc16_upper, :dec16_upper, b16_upper }, + { :enc16_lower, :dec16_lower, b16_lower }, + { :enc64, :dec64, b64 }, + { :enc32_upper, :dec32_upper, b32_upper }, + { :enc32_lower, :dec32_lower, b32_lower }, + { :enc64_url, :dec64_url, b64_url }, + { :enc32_hex_upper, :dec32_hex_upper, b32_hex_upper }, + { :enc32_hex_lower, :dec32_hex_lower, b32_hex_lower } + ], fn({enc, dec, alphabet}) -> + for {encoding, value} <- Enum.with_index(alphabet) do defp unquote(enc)(unquote(value)), do: unquote(encoding) defp unquote(dec)(unquote(encoding)), do: unquote(value) end @@ -32,15 +39,25 @@ defmodule Base do @doc """ Encodes a binary string into a base 16 encoded string. + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.encode16("foobar") "666F6F626172" + iex> Base.encode16("Hello World", lowercase: true) + "48656c6c6f20576f726c64" + """ - @spec encode16(binary) :: binary - def encode16(data) when is_binary(data) do - do_encode16(data, &enc16/1) + @spec encode16(binary, Keyword.t) :: binary + def encode16(data, opts \\ []) when is_binary(data) do + if opts[:lowercase] do + do_encode16(data, &enc16_lower/1) + else + do_encode16(data, &enc16_upper/1) + end end @doc """ @@ -55,15 +72,21 @@ defmodule Base do | 2| 2| 6| 6| 10| A| 14| E| | 3| 3| 7| 7| 11| B| 15| F| + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.decode16("666F6F626172") {:ok, "foobar"} + iex> Base.decode16("48656c6c6f20576f726c64", lowercase: true) + {:ok, "Hello World"} + """ - @spec decode16(binary) :: { :ok, binary } | :error - def decode16(string) when is_binary(string) do - { :ok, decode16!(string) } + @spec decode16(binary, Keyword.t) :: { :ok, binary } | :error + def decode16(string, opts \\ []) when is_binary(string) do + { :ok, decode16!(string, opts) } rescue ArgumentError -> :error end @@ -71,6 +94,9 @@ defmodule Base do @doc """ Decodes a base 16 encoded string into a binary string. + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. @@ -79,10 +105,17 @@ defmodule Base do iex> Base.decode16!("666F6F626172") "foobar" + iex> Base.decode16!("48656c6c6f20576f726c64", lowercase: true) + "Hello World" + """ - @spec decode16!(binary) :: binary - def decode16!(string) when is_binary(string) do - do_decode16(string, &dec16/1) + @spec decode16!(binary, Keyword.t) :: binary + def decode16!(string, opts \\ []) when is_binary(string) do + if opts[:lowercase] do + do_decode16(string, &dec16_lower/1) + else + do_decode16(string, &dec16_upper/1) + end end @doc """ @@ -132,7 +165,7 @@ defmodule Base do """ @spec decode64(binary) :: { :ok, binary } | :error def decode64(string) when is_binary(string) do - { :ok, do_decode64(string, &dec64/1) } + { :ok, decode64!(string) } rescue ArgumentError -> :error end @@ -140,8 +173,6 @@ defmodule Base do @doc """ Decodes a base 64 encoded string into a binary string. - The following alphabet is used both for encoding and decoding: - An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. @@ -168,7 +199,7 @@ defmodule Base do """ @spec url_encode64(binary) :: binary def url_encode64(data) when is_binary(data) do - do_encode64(data, &enc64url/1) + do_encode64(data, &enc64_url/1) end @doc """ @@ -205,7 +236,7 @@ defmodule Base do """ @spec url_decode64(binary) :: { :ok, binary } | :error def url_decode64(string) when is_binary(string) do - { :ok, do_decode64(string, &dec64url/1) } + { :ok, url_decode64!(string) } rescue ArgumentError -> :error end @@ -225,21 +256,31 @@ defmodule Base do """ @spec url_decode64!(binary) :: binary def url_decode64!(string) when is_binary(string) do - do_decode64(string, &dec64url/1) + do_decode64(string, &dec64_url/1) end @doc """ Encodes a binary string into a base 32 encoded string. + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.encode32("foobar") "MZXW6YTBOI======" + iex> Base.encode32("foobar", lowercase: true) + "mzxw6ytboi======" + """ - @spec encode32(binary) :: binary - def encode32(data) when is_binary(data) do - do_encode32(data, &enc32/1) + @spec encode32(binary, Keyword.t) :: binary + def encode32(data, opts \\ []) when is_binary(data) do + if opts[:lowercase] do + do_encode32(data, &enc32_lower/1) + else + do_encode32(data, &enc32_upper/1) + end end @doc """ @@ -259,15 +300,21 @@ defmodule Base do | 7| H| 16| Q| 25| Z| | | | 8| I| 17| R| 26| 2| | | + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.decode32("MZXW6YTBOI======") {:ok, "foobar"} + iex> Base.decode32("mzxw6ytboi======", lowercase: true) + {:ok, "foobar"} + """ - @spec decode32(binary) :: { :ok, binary } | :error - def decode32(string) do - { :ok, do_decode32(string, &dec32/1) } + @spec decode32(binary, Keyword.t) :: { :ok, binary } | :error + def decode32(string, opts \\ []) do + { :ok, decode32!(string, opts) } rescue ArgumentError -> :error end @@ -275,6 +322,9 @@ defmodule Base do @doc """ Decodes a base 32 encoded string into a binary string. + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. @@ -283,25 +333,42 @@ defmodule Base do iex> Base.decode32!("MZXW6YTBOI======") "foobar" + iex> Base.decode32!("mzxw6ytboi======", lowercase: true) + "foobar" + """ - @spec decode32!(binary) :: binary - def decode32!(string) do - do_decode32(string, &dec32/1) + @spec decode32!(binary, Keyword.t) :: binary + def decode32!(string, opts \\ []) do + if opts[:lowercase] do + do_decode32(string, &dec32_lower/1) + else + do_decode32(string, &dec32_upper/1) + end end @doc """ Encodes a binary string into a base 32 encoded string with an extended hexadecimal alphabet. + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.hex_encode32("foobar") "CPNMUOJ1E8======" + iex> Base.hex_encode32("foobar", lowercase: true) + "cpnmuoj1e8======" + """ - @spec hex_encode32(binary) :: binary - def hex_encode32(data) when is_binary(data) do - do_encode32(data, &enc32hex/1) + @spec hex_encode32(binary, Keyword.t) :: binary + def hex_encode32(data, opts \\ []) when is_binary(data) do + if opts[:lowercase] do + do_encode32(data, &enc32_hex_lower/1) + else + do_encode32(data, &enc32_hex_upper/1) + end end @doc """ @@ -322,15 +389,21 @@ defmodule Base do | 7| 7| 16| G| 25| P| | | | 8| 8| 17| H| 26| Q| | | + By default an uppercase alphabet is used. An alternate lowercase alphabet + can be selected by setting the `lowercase` option set to `true`. + ## Examples iex> Base.hex_decode32("CPNMUOJ1E8======") {:ok, "foobar"} + iex> Base.hex_decode32("cpnmuoj1e8======", lowercase: true) + {:ok, "foobar"} + """ - @spec hex_decode32(binary) :: { :ok, binary } | :error - def hex_decode32(string) when is_binary(string) do - { :ok, do_decode32(string, &dec32hex/1) } + @spec hex_decode32(binary, Keyword.t) :: { :ok, binary } | :error + def hex_decode32(string, opts \\ []) when is_binary(string) do + { :ok, hex_decode32!(string, opts) } rescue ArgumentError -> :error end @@ -347,10 +420,17 @@ defmodule Base do iex> Base.hex_decode32!("CPNMUOJ1E8======") "foobar" + iex> Base.hex_decode32!("cpnmuoj1e8======", lowercase: true) + "foobar" + """ - @spec hex_decode32!(binary) :: binary - def hex_decode32!(string) when is_binary(string) do - do_decode32(string, &dec32hex/1) + @spec hex_decode32!(binary, Keyword.t) :: binary + def hex_decode32!(string, opts \\ []) when is_binary(string) do + if opts[:lowercase] do + do_decode32(string, &dec32_hex_lower/1) + else + do_decode32(string, &dec32_hex_upper/1) + end end defp do_encode16(<<>>, _), do: <<>> @@ -370,14 +450,14 @@ defmodule Base do defp do_encode64(<<>>, _), do: <<>> defp do_encode64(data, enc) do - split = 3 * div(byte_size(data), 3) - <> = data + split = 6 * div(bit_size(data), 6) + <> = data main = for <>, into: <<>>, do: <> case rest do - <> -> - <> - <> -> - <> + <> -> + <> + <> -> + <> <<>> -> main end @@ -385,16 +465,16 @@ defmodule Base do defp do_decode64(<<>>, _), do: <<>> defp do_decode64(string, dec) when rem(byte_size(string), 4) == 0 do - split = byte_size(string) - 4 + split = byte_size(string) - 3 <> = string main = for <>, into: <<>>, do: <> case rest do - <> -> - <> - <> -> - <> - <> -> - <> + <> -> + <> + <> -> + <> + <> -> + <> <<>> -> main end @@ -405,26 +485,18 @@ defmodule Base do defp do_encode32(<<>>, _), do: <<>> defp do_encode32(data, enc) do - split = 5 * div(byte_size(data), 5) - <> = data + split = 5 * div(bit_size(data), 5) + <> = data main = for <>, into: <<>>, do: <> case rest do - <> -> - <> - <> -> - <> - <> -> - <> - <> -> - <> + <> -> + <> + <> -> + <> + <> -> + <> + <> -> + <> <<>> -> main end @@ -432,27 +504,20 @@ defmodule Base do defp do_decode32(<<>>, _), do: <<>> defp do_decode32(string, dec) when rem(byte_size(string), 8) == 0 do - split = byte_size(string) - 8 + split = byte_size(string) - 7 <> = string main = for <>, into: <<>>, do: <> case rest do - <> -> - <> - <> -> - <> - <> -> - <> - <> -> - <> - <> -> - <> + <> -> + <> + <> -> + <> + <> -> + <> + <> -> + <> + <> -> + <> <<>> -> main end diff --git a/lib/elixir/test/elixir/base_test.exs b/lib/elixir/test/elixir/base_test.exs index da79251ab61..f8e48a17b08 100644 --- a/lib/elixir/test/elixir/base_test.exs +++ b/lib/elixir/test/elixir/base_test.exs @@ -3,14 +3,10 @@ Code.require_file "test_helper.exs", __DIR__ defmodule BaseTest do use ExUnit.Case, async: true import Base - + test "encode16" do assert "" == encode16("") assert "66" == encode16("f") - assert "666F" == encode16("fo") - assert "666F6F" == encode16("foo") - assert "666F6F62" == encode16("foob") - assert "666F6F6261" == encode16("fooba") assert "666F6F626172" == encode16("foobar") assert "A1B2C3D4E5F67891" == encode16(<<161, 178, 195, 212, 229, 246, 120, 145>>) end @@ -18,30 +14,21 @@ defmodule BaseTest do test "decode16" do assert { :ok, "" } == decode16("") assert { :ok, "f" } == decode16("66") - assert { :ok, "fo" } == decode16("666F") - assert { :ok, "foo" } == decode16("666F6F") - assert { :ok, "foob" } == decode16("666F6F62") - assert { :ok, "fooba" } == decode16("666F6F6261") assert { :ok, "foobar" } == decode16("666F6F626172") assert { :ok, <<161, 178, 195, 212, 229, 246, 120, 145>> } == decode16("A1B2C3D4E5F67891") end - + test "decode16!" do assert "" == decode16!("") - assert "f" == decode16!("66") - assert "fo" == decode16!("666F") - assert "foo" == decode16!("666F6F") - assert "foob" == decode16!("666F6F62") - assert "fooba" == decode16!("666F6F6261") assert "foobar" == decode16!("666F6F626172") assert <<161, 178, 195, 212, 229, 246, 120, 145>> == decode16!("A1B2C3D4E5F67891") end - test "decode16 lowercase" do + test "decode16 invalid lowercase" do assert :error == decode16("e8") end - test "decode16! lowercase" do + test "decode16! invalid lowercase" do assert_raise ArgumentError, "non-alphabet digit found: e", fn -> decode16!("e8") end @@ -60,17 +47,41 @@ defmodule BaseTest do test "decode16 odd-length string" do assert :error == decode16("666") end - + test "decode16! odd-length string" do assert_raise ArgumentError, "odd-length string", fn -> decode16!("666") end end + test "encode16 lowercase" do + assert "" == encode16("", lowercase: true) + assert "a1b2c3d4e5f67891" == encode16(<<161, 178, 195, 212, 229, 246, 120, 145>>, lowercase: true) + end + + test "decode16 valid lowercase" do + assert { :ok, "" } == decode16("", lowercase: true) + assert { :ok, <<232>>} == decode16("e8", lowercase: true) + end + + test "decode16! valid lowercase" do + assert <<232>> == decode16!("e8", lowercase: true) + end + + test "decode16 invalid uppercase" do + assert :error == decode16("E8", lowercase: true) + end + + test "decode16! invalid uppercase" do + assert_raise ArgumentError, "non-alphabet digit found: E", fn -> + decode16!("E8", lowercase: true) + end + end + test "encode64 empty" do assert "" == encode64("") end - + test "encode64 two pads" do assert "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" == encode64("Aladdin:open sesame") end @@ -119,7 +130,7 @@ defmodule BaseTest do test "decode64 non-alphabet digit" do assert :error == decode64("Zm9)") end - + test "decode64! non-alphabet digit" do assert_raise ArgumentError, "non-alphabet digit found: )", fn -> decode64!("Zm9)") @@ -129,7 +140,7 @@ defmodule BaseTest do test "decode64 incorrect padding" do assert :error == decode64("SGVsbG8gV29ybGQ") end - + test "decode64! incorrect padding" do assert_raise ArgumentError, "incorrect padding", fn -> decode64!("SGVsbG8gV29ybGQ") @@ -139,7 +150,7 @@ defmodule BaseTest do test "url_encode64 empty" do assert "" == url_encode64("") end - + test "url_encode64 two pads" do assert "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" == url_encode64("Aladdin:open sesame") end @@ -157,7 +168,7 @@ defmodule BaseTest do refute "/3/+/A==" == url_encode64(<<255,127,254,252>>) assert "_3_-_A==" == url_encode64(<<255,127,254,252>>) end - + test "url_decode64 empty" do assert { :ok, "" } == url_decode64("") end @@ -165,7 +176,7 @@ defmodule BaseTest do test "url_decode64! empty" do assert "" == url_decode64!("") end - + test "url_decode64 two pads" do assert { :ok, "Aladdin:open sesame" } == url_decode64("QWxhZGRpbjpvcGVuIHNlc2FtZQ==") end @@ -193,7 +204,7 @@ defmodule BaseTest do test "url_decode64 non-alphabet digit" do assert :error == url_decode64("Zm9)") end - + test "url_decode64! non-alphabet digit" do assert_raise ArgumentError, "non-alphabet digit found: )", fn -> url_decode64!("Zm9)") @@ -203,17 +214,17 @@ defmodule BaseTest do test "url_decode64 incorrect padding" do assert :error == url_decode64("SGVsbG8gV29ybGQ") end - + test "url_decode64! incorrect padding" do assert_raise ArgumentError, "incorrect padding", fn -> url_decode64!("SGVsbG8gV29ybGQ") end end - + test "encode32 empty" do assert "" == encode32("") end - + test "encode32 one pad" do assert "MZXW6YQ=" == encode32("foob") end @@ -221,7 +232,7 @@ defmodule BaseTest do test "encode32 three pads" do assert "MZXW6===" == encode32("foo") end - + test "encode32 four pads" do assert "MZXQ====" == encode32("fo") end @@ -242,7 +253,7 @@ defmodule BaseTest do test "decode32! empty" do assert "" == decode32!("") end - + test "decode32 one pad" do assert { :ok, "foob" } == decode32("MZXW6YQ=") end @@ -288,7 +299,7 @@ defmodule BaseTest do test "decode32 non-alphabet digit" do assert :error == decode32("MZX)6YTB") end - + test "decode32! non-alphabet digit" do assert_raise ArgumentError, "non-alphabet digit found: )", fn -> decode32!("MZX)6YTB") @@ -298,17 +309,41 @@ defmodule BaseTest do test "decode32 incorrect padding" do assert :error == decode32("MZXW6YQ") end - + test "decode32! incorrect padding" do assert_raise ArgumentError, "incorrect padding", fn -> decode32!("MZXW6YQ") end end + test "encode32 lowercase" do + assert "" == encode32("", lowercase: true) + assert "mzxw6ytb" == encode32("fooba", lowercase: true) + end + + test "decode32 valid lowercase" do + assert {:ok, ""} == decode32("", lowercase: true) + assert {:ok, "fooba"} == decode32("mzxw6ytb", lowercase: true) + end + + test "decode32! valid lowercase" do + assert "fooba" == decode32!("mzxw6ytb", lowercase: true) + end + + test "decode32 invalid uppercase" do + assert :error == decode32("MZXW6YTB", lowercase: true) + end + + test "decode32! invalid uppercase" do + assert_raise ArgumentError, "non-alphabet digit found: M", fn -> + decode32!("MZXW6YTB", lowercase: true) + end + end + test "hex_encode32 empty" do assert "" == hex_encode32("") end - + test "hex_encode32 one pad" do assert "CPNMUOG=" == hex_encode32("foob") end @@ -316,7 +351,7 @@ defmodule BaseTest do test "hex_encode32 three pads" do assert "CPNMU===" == hex_encode32("foo") end - + test "hex_encode32 four pads" do assert "CPNG====" == hex_encode32("fo") end @@ -393,11 +428,39 @@ defmodule BaseTest do test "hex_decode32 incorrect padding" do assert :error == hex_decode32("CPNMUOG") end - + test "hex_decode32! incorrect padding" do assert_raise ArgumentError, "incorrect padding", fn -> hex_decode32!("CPNMUOG") end end - + + test "hex_decode32 invalid lowercase" do + assert :error == hex_decode32("cpnmuoj1") + end + + test "hex_encode32 lowercase" do + assert "" == hex_encode32("", lowercase: true) + assert "cpnmuoj1" == hex_encode32("fooba", lowercase: true) + end + + test "hex_decode32 valid lowercase" do + assert {:ok, ""} == hex_decode32("", lowercase: true) + assert {:ok, "fooba"} == hex_decode32("cpnmuoj1", lowercase: true) + end + + test "hex_decode32! valid lowercase" do + assert "fooba" == hex_decode32!("cpnmuoj1", lowercase: true) + end + + test "hex_decode32 invalid uppercase" do + assert :error == hex_decode32("CPNMUOJ1", lowercase: true) + end + + test "hex_decode32! invalid uppercase" do + assert_raise ArgumentError, "non-alphabet digit found: C", fn -> + hex_decode32!("CPNMUOJ1", lowercase: true) + end + end + end From 0943418bf98d650a244a285e6c46c59052b1424a Mon Sep 17 00:00:00 2001 From: Paulo Almeida Date: Wed, 2 Apr 2014 09:50:56 -0700 Subject: [PATCH 2/2] Fixed typo in function @docs --- lib/elixir/lib/base.ex | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/elixir/lib/base.ex b/lib/elixir/lib/base.ex index 47c6ad343b7..f3210ff8764 100644 --- a/lib/elixir/lib/base.ex +++ b/lib/elixir/lib/base.ex @@ -40,7 +40,7 @@ defmodule Base do Encodes a binary string into a base 16 encoded string. By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples @@ -73,7 +73,7 @@ defmodule Base do | 3| 3| 7| 7| 11| B| 15| F| By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples @@ -95,7 +95,7 @@ defmodule Base do Decodes a base 16 encoded string into a binary string. By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. @@ -263,7 +263,7 @@ defmodule Base do Encodes a binary string into a base 32 encoded string. By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples @@ -301,7 +301,7 @@ defmodule Base do | 8| I| 17| R| 26| 2| | | By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples @@ -323,7 +323,7 @@ defmodule Base do Decodes a base 32 encoded string into a binary string. By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. An `ArgumentError` exception is raised if the padding is incorrect or a non-alphabet character is present in the string. @@ -351,7 +351,7 @@ defmodule Base do extended hexadecimal alphabet. By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples @@ -390,7 +390,7 @@ defmodule Base do | 8| 8| 17| H| 26| Q| | | By default an uppercase alphabet is used. An alternate lowercase alphabet - can be selected by setting the `lowercase` option set to `true`. + can be selected by setting the `lowercase` option to `true`. ## Examples