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
}
<> | <> -> {
let assert <> = <<
num(a):5,
num(b):5,
num(c):5,
num(d):5,
num(e):5,
num(f):5,
num(g):5,
0:5,
>>
out
}
<> -> <<
num(a):5,
num(b):5,
num(c):5,
num(d):5,
num(e):5,
num(f):5,
num(g):5,
num(h):5,
do_decode(rest):bits,
>>
_ -> panic as "Invalid base32 string"
}
}
fn num(a) {
case a {
a if a >= 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
}
}