Every base encoding, one shape: base2 through base85, bech32 and multibase for MoonBit.
let data = b"moonbase"
let pem = "bW9vbmJhc2U=\n" // a PEM body, newline and all
@base64.encode(data[:]) // "bW9vbmJhc2U="
@base64.encode(data[:], kind=Url, padding=false) // "bW9vbmJhc2U"
@base64.encode_bytes(data[:]) // the ASCII bytes, no String on the way
@base64.decode("bW9vbmJhc2U=") // b"moonbase"
@base64.decode_lossy(pem) // b"moonbase"moon add moonbitstack/moonbase// moon.pkg
import {
"moonbitstack/moonbase/base64",
}| Face | Signature | For |
|---|---|---|
| encode | (BytesView, …) -> String | the ordinary case |
| encode_bytes | (BytesView, …) -> Bytes | wire formats that hold bytes — an HTTP header, a gRPC metadata value — with no round trip through String |
| decode | (StringView, …) -> Bytes raise Malformed | input you want checked |
| decode_bytes | (BytesView, …) -> Bytes raise Malformed | the same, for callers who never had a string |
| decode_lossy | (StringView, …) -> Bytes | a PEM body full of newlines, a fingerprint full of colons |
@base32.encode(data[:], kind=Hex) // "DLNMURJ2C5PMA==="
@base32.encode(data[:], kind=Crockford) // "DNQPYVK2C5SPA"
@base16.encode(data[:], kind=Upper) // "6D6F6F6E62617365"
@base64.encode(data[:], padding=false) // "bW9vbmJhc2U"
@base85.encode(b"\x00\xff\x01\xfe"[:], kind=Z85) // "0ri90"@base64.decode("Zg==", padding=true, strict=true) // b"f"
@base64.decode("Zh==", strict=true) // raises Padding(at=1)
@base64.decode("Zg==", padding=false) // raises Padding(at=2)let sink = @base64.sink()
sink.write(b"moon"[:])
sink.write(b"base"[:])
sink.finish() // "bW9vbmJhc2U="
let source = @base64.source()
source.write("bW9vbm") // six characters are four bytes and four bits
source.drain() // b"moon" — the leftover bits stay behind
source.write("Jhc2U=")
source.finish() // b"base"@base36.encode_int(123456789) // "21i3v9"
@base62.encode_int(123456789) // "8M0kX"
@base36.decode_int("21i3v9") // 123456789@moonbase.encode_big(@bigint.BigInt::from_int(123456789), hex) // "75bcd15"
@moonbase.decode_big("75bcd15", hex) // the same numbertry {
@base64.decode("Zm*vYg==")
} catch {
failure => match failure {
Bad(at~, char~) => println("bad " + char.to_string() + " at " + at.to_string())
Truncated(at~) => println("truncated at " + at.to_string())
Padding(at~) => println("padding at " + at.to_string())
Checksum(at~) => println("checksum at " + at.to_string())
}
} noraise {
_ => println("decoded")
}let crockford = @moonbase.Alphabet::new("0123456789ABCDEFGHJKMNPQRSTVWXYZ")
@moonbase.encode(data[:], crockford) // "6TVVFDSH62WV5"@multibase.encode(data[:], base=Base58Btc) // "zKJfFLz7PRba"
@multibase.detect("zKJfFLz7PRba") // Some(Base58Btc)
@multibase.decode("zKJfFLz7PRba") // b"moonbase"@bech32.encode("moonbase", data[:]) // "moonbase1d4hk7mnzv9ek2s84pra"
@bech32.encode("moonbase", data[:], kind=Bech32m) // "moonbase1d4hk7mnzv9ek29m9dxl"
@bech32.decode_words("moonbase1d4hk7mnzv9ek2s84pra") // { hrp: "moonbase", words: … }| Package | Specification | Notes |
|---|---|---|
| base2 | multibase 0 | one bit a character; eight characters a byte |
| base8 | multibase 7 | three bits a character — a bit packing, not an octal of a number |
| base10 | multibase 9 | the bytes as one decimal integer, so a leading zero byte stays a leading 0 |
| base16 | RFC 4648 §8 | byte-aligned, so leading zeros survive; encode_colons writes fingerprints |
| base32 | RFC 4648 §6, §7 | kind=Hex keeps byte order under sorting; Crockford and Z for people |
| base36 | multibase k / K | numbers and identifiers |
| base45 | RFC 9285 | two bytes in three characters a QR code's alphanumeric mode can hold; no padding |
| base58 | multibase z | Flickr and Ripple alphabets, plus encode_check / decode_check |
| base62 | — | digits, upper, lower; short identifiers |
| base64 | RFC 4648 §4, §5 | kind=Url for tokens and file names; decode_any reads either alphabet |
| base85 | Adobe, ZeroMQ RFC 32, RFC 1924 | kind=Ascii85, kind=Z85, kind=Ipv6 — four bytes in five characters, three ways |
| bech32 | BIP 173, BIP 350 | a human-readable prefix, five-bit groups and a BCH checksum; kind=Bech32m for version 1 and up |
| multibase | multiformats | one prefix character, from 0 for base2 to a rocket for base256emoji |
moon run src/examples/minimal --target wasm-gc
moon run src/examples/tour --target wasm-gc
moon run src/examples/integration --target wasm-gcpub struct Sink {
// private fields
}let sink = @base64.sink()
sink.write(b"foo"[:])
sink.write(b"bar"[:])
sink.finish() // "Zm9vYmFy"pub struct Source {
// private fields
}Install
Download zipEvery base encoding, one shape: base2 through base85, bech32 and multibase for MoonBit.