Skip to content
Kavachकवच

Base64

● Intermediate3 minBefore this: BytesSpec 14.20

std.base64 writes bytes as text and reads them back, in the standard alphabet or the URL-safe one. Tokens, cookies and email use it.

use std.base64

fn main() ! Base64Error {
    const data = "hi?>".bytes()
    print(base64.encode(data))
    print(base64.encode(data, url: true, pad: false))
    print((try base64.decode("aGk/Pg==")).text() ?? "")
    print((try base64.decode("aGk_Pg", url: true)).text() ?? "")
}

The program ran and printed:

kavach run encode.kav

aGk/Pg==aGk_Pghi?>hi?>
encode.kav: Kavach code, then what running it prints
  • url: true uses - and _ instead of + and /, so the text can go in a URL. Tokens such as JWTs use it, with pad: false.
  • It needs no capability: it changes nothing outside the program.

Strict decoding

Decoding is strict, so one value has one text, which signed tokens rely on. Padding may be left out, but when it is there it must be right:

use std.base64

fn show(text: String) {
    match base64.decode(text) {
        ok(data) => print("{text}: {data.len()} bytes")
        err(Base64Error.BadCharacter(at)) => print("{text}: a bad character at {at}")
        err(Base64Error.BadLength) => print("{text}: a length no encoding gives")
        err(Base64Error.BadPadding) => print("{text}: wrong padding")
        err(Base64Error.ExtraBits) => print("{text}: bits after the last byte")
    }
}

fn main() {
    for text in ["aGk=", "aGk", "aG!=", "a", "aGk==", "aGl="] {
        show(text)
    }
}

The program ran and printed:

kavach run strict.kav

aGk=: 2 bytesaGk: 2 bytesaG!=: a bad character at 2a: a length no encoding givesaGk==: wrong paddingaGl=: bits after the last byte
strict.kav: Kavach code, then what running it prints
FunctionGives
base64.encode(data, url: false, pad: true) -> Stringdata (Bytes) as base64 text: URL-safe when url, with = padding when pad
base64.decode(text, url: false) -> Bytes ! Base64ErrorThe bytes text encodes, in the alphabet url picks