Skip to content
heff

std.base32

Base32 (RFC 4648): bytes written as text, each five of them as eight digits of 32, the text padded with = to a multiple of eight. encode and decode take the standard digits, A-Z and 2-7 (Go’s base32.StdEncoding); encodeHex and decodeHex the “extended hex” ones, 0-9 and A-V, which keep the bytes’ order (Go’s base32.HexEncoding), padded too. The letters are upper case only. Reading is strict: the padding is required, nothing but digits and it is read (no white space), and the bits left over in the last digit are 0. Import it by a name, import std.base32 as Base32.

import bytes as Bytes
import std.base32 as Base32
-- | >>> secret
-- | "JBSWY3DPEE======"
secret : String
secret = Base32.encode (Bytes.fromString "Hello!")

encode

encode : Bytes -> String

The bytes as base32’s standard digits, padded with = (Go’s base32.StdEncoding). RFC 4648’s examples:

>>> List.map (\s -> encode (Bytes.fromString s)) ["", "f", "fo", "foo", "foob", "fooba", "foobar"]
["", "MY======", "MZXQ====", "MZXW6===", "MZXW6YQ=", "MZXW6YTB", "MZXW6YTBOI======"]
>>> encode b[0, 68, 50, 20, 199, 66, 84, 182, 53, 207, 132, 101, 58, 86, 215, 198, 117, 190, 119, 223]
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
>>> encode b[255, 255, 255, 255, 255]
"77777777"

decode

decode : String -> Maybe Bytes

The bytes the standard digits are, read strictly: Nothing where the text is not a multiple of eight digits long, has anything but digits and its padding (white space and lower case too), lacks its padding, or has bits left over in its last digit that are not 0.

>>> List.map decode ["", "MY======", "MZXQ====", "MZXW6===", "MZXW6YQ=", "MZXW6YTB", "MZXW6YTBOI======"]
[Just b[], Just b["f"], Just b["fo"], Just b["foo"], Just b["foob"], Just b["fooba"], Just b["foobar"]]
>>> decode "77777777"
Just b[255, 255, 255, 255, 255]

(no padding, padding but at the end, too much or too little of it, white space, lower case, the hex digits, bits left over)

>>> List.map decode ["MY", "MZXW6", "MY======MZXW6YTB", "M=======", "MZX=====", "MZXW6Y==", "MZXW6YTB\n", "MZ XW6YTB", "mzxw6ytb", "CO======", "MZ======", "MZXR====", "MZXW7===", "MZXW6YR=", "========"]
[Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing]

encodeHex

encodeHex : Bytes -> String

The bytes as the “extended hex” digits, 0-9 then A-V, padded with = (Go’s base32.HexEncoding). RFC 4648’s examples:

>>> List.map (\s -> encodeHex (Bytes.fromString s)) ["", "f", "fo", "foo", "foob", "fooba", "foobar"]
["", "CO======", "CPNG====", "CPNMU===", "CPNMUOG=", "CPNMUOJ1", "CPNMUOJ1E8======"]
>>> encodeHex b[0, 68, 50, 20, 199, 66, 84, 182, 53, 207, 132, 101, 58, 86, 215, 198, 117, 190, 119, 223]
"0123456789ABCDEFGHIJKLMNOPQRSTUV"

decodeHex

decodeHex : String -> Maybe Bytes

The bytes the “extended hex” digits are, read as strictly as decode reads.

>>> List.map decodeHex ["", "CO======", "CPNG====", "CPNMU===", "CPNMUOG=", "CPNMUOJ1", "CPNMUOJ1E8======"]
[Just b[], Just b["f"], Just b["fo"], Just b["foo"], Just b["foob"], Just b["fooba"], Just b["foobar"]]
>>> List.map decodeHex ["MY======", "cpnmuoj1", "CPNMUOJ1E8", "CP======", "CPNMUOJW"]
[Nothing, Nothing, Nothing, Nothing, Nothing]