import gleam/bit_array @external(erlang, "multiformats_ffi", "decode32") pub fn decode(encoded: String) -> BitArray { do_decode(bit_array.from_string(encoded)) } fn do_decode(encoded) { case encoded { <<>> -> <<>> <> | <> -> { let assert <> = << num(a):5, num(b):5, 0:6, >> out } <> | <> -> { let assert <> = << num(a):5, num(b):5, num(c):5, num(d):5, 0:4, >> out } <> | <> -> { let assert <> = << num(a):5, num(b):5, num(c):5, num(d):5, num(e):5, 0:7, >> out } <> | <= 65 && a <= 90 -> a - 65 a if a >= 97 && a <= 122 -> a - 97 a if a >= 50 && a <= 55 -> a - 24 _ -> panic as "Invalid base32 charachter" } } @external(erlang, "multiformats_ffi", "encode32") pub fn encode(input: BitArray) -> String { let assert Ok(out) = bit_array.to_string(do_encode(input)) out } fn char(n) { case n { n if n >= 0 && n <= 25 -> n + 65 n if n >= 26 && n <= 31 -> n + 24 _ -> panic } } fn do_encode(input) { case input { <<>> -> <<>> <> -> <> <> -> << char(a), char(b), char(c), char(d * 16), "====", >> <> -> << char(a), char(b), char(c), char(d), char(e * 2), "===", >> <> -> << char(a), char(b), char(c), char(d), char(e), char(f), char(g * 8), "=", >> <> -> << char(a), char(b), char(c), char(d), char(e), char(f), char(g), char(h), do_encode(rest):bits, >> _ -> panic } }