Skip to content

Instantly share code, notes, and snippets.

@pma
Last active August 29, 2015 13:57
Show Gist options
  • Save pma/9765560 to your computer and use it in GitHub Desktop.
Save pma/9765560 to your computer and use it in GitHub Desktop.
defmodule Base do
import Bitwise
b16_alphabet =
'0123456789ABCDEF'
|> Enum.with_index
for {encoding, value} <- b16_alphabet do
defp enc16(unquote(value)), do: unquote(encoding)
defp dec16(unquote(encoding)), do: unquote(value)
end
b64_alphabet =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|> Enum.with_index
for {encoding, value} <- b64_alphabet do
defp enc64(unquote(value)), do: unquote(encoding)
defp dec64(unquote(encoding)), do: unquote(value)
end
def encode16(data) do
for <<c::4 <- data>>, into: <<>>, do: <<enc16(c)::8>>
end
def decode16(string) when rem(byte_size(string), 2) == 0 do
for <<c1::8, c2::8 <- string>>, into: <<>> do
<<dec16(c1)::4, dec16(c2)::4>>
end
end
def encode64(data) do
split = 3 * div(byte_size(data), 3)
<<main::[size(split), binary], rest::binary>> = data
main = for <<c::6 <- main>>, into: <<>>, do: <<enc64(c)::8>>
case rest do
<<a::6, b::6, c::4>> ->
<<main::binary, enc64(a)::8, enc64(b)::8, enc64(bsl(c, 2))::8, ?=>>
<<a::6, b::2>> ->
<<main::binary, enc64(a)::8, enc64(bsl(b, 4))::8, ?=, ?=>>
<<>> ->
main
end
end
def decode64(string) when rem(byte_size(string), 4) == 0 do
for <<group::32 <- string>>, into: <<>> do
case <<group::32>> do
<<c1::8, c2::8, ?=, ?=>> ->
<<dec64(c1)::6, bsr(dec64(c2), 4)::2>>
<<c1::8, c2::8, c3::8, ?=>> ->
<<dec64(c1)::6, dec64(c2)::6, bsr(dec64(c3), 2)::4>>
<<c1::8, c2::8, c3::8, c4::8>> ->
<<dec64(c1)::6, dec64(c2)::6, dec64(c3)::6, dec64(c4)::6>>
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment