62 lines
1.4 KiB
Typst
62 lines
1.4 KiB
Typst
#import "utils.typ": z-fill, bin-to-int
|
|
#let b32-alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
|
|
|
/// Decodes a base32-encoded value
|
|
/// #test(
|
|
/// `jumble.b32-decode("LFHVKUCJ") == bytes("YOUPI")`
|
|
/// )
|
|
/// ```example
|
|
/// #str(b32-decode("LFHVKUCJ"))
|
|
/// ```
|
|
/// -> bytes
|
|
#let b32-decode(
|
|
/// -> str
|
|
encoded
|
|
) = {
|
|
let decoded-bin = ()
|
|
for char in encoded {
|
|
if char == "=" {
|
|
break
|
|
}
|
|
let i = b32-alphabet.position(char)
|
|
decoded-bin += z-fill(str(i, base: 2), 5).clusters().map(int)
|
|
}
|
|
decoded-bin = decoded-bin.slice(
|
|
0,
|
|
calc.div-euclid(decoded-bin.len(), 8) * 8
|
|
)
|
|
let decoded-bytes = decoded-bin.chunks(8).map(bin-to-int)
|
|
return bytes(decoded-bytes)
|
|
}
|
|
|
|
/// Encodes a value in base32
|
|
/// #test(
|
|
/// `jumble.b32-encode(bytes("YOUPI")) == "LFHVKUCJ"`
|
|
/// )
|
|
/// ```example
|
|
/// #b32-encode(bytes("YOUPI"))
|
|
/// ```
|
|
/// -> str
|
|
#let b32-encode(
|
|
/// -> bytes
|
|
decoded
|
|
) = {
|
|
let encoded = ""
|
|
let decoded-bin = array(decoded).map(b => z-fill(str(b, base: 2), 8)).join()
|
|
decoded-bin = decoded-bin.clusters().map(int)
|
|
let groups = decoded-bin.chunks(40)
|
|
for group in groups {
|
|
let chars = group.chunks(5)
|
|
if chars.last().len() != 5 {
|
|
chars.last() += (0,) * (5 - chars.last().len())
|
|
}
|
|
let chars = chars.map(bin-to-int)
|
|
.map(c => b32-alphabet.at(c))
|
|
encoded += chars.join()
|
|
let pad = 8 - chars.len()
|
|
if pad != 0 {
|
|
encoded += "=" * pad
|
|
}
|
|
}
|
|
return encoded
|
|
} |