Why does base32 encoding using Crockford alphabet not produce the same results as the spec?
I am trying to understand what method of base32 encoding is used to produce the common ULID string specified in the spec, leading with usually 01G as it doesn't seem to be the method defined in rfc4648 with the Crockford alphabet.
Using any rfc4648 compliant base32 encoder with the Crockford32 alphabet ends up producing a different resulting string, usually preceding with 063
For example, using Golang and the oklog/ulid package:
package main
import (
"encoding/base32"
"fmt"
"github.com/oklog/ulid/v2"
)
const crockford32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
var crockfordEncoder = base32.NewEncoding(crockford32).WithPadding(base32.NoPadding)
func main() {
id := ulid.Make()
fmt.Printf("encoding/base32: \t%s\n", crockfordEncoder.EncodeToString(id[:]))
fmt.Printf("ULID.String(): \t\t%s\n", id.String())
}
// output
// encoding/base32: 063A7TAANJDY8Q2ASDD5EE0F2R
// ULID.String(): 01GTHYJJNCKFJ5RJPBB9BKG3RP
Here is the code also in the Go playground - be aware the time is frozen is this sandbox. https://go.dev/play/p/T9FD_2uJhCZ
Hi!
ULID uses MOD operation to encode to Crockford's base-32, which produces a different result than RFC-4648.
See this comment: https://github.com/ulid/spec/issues/73#issuecomment-1247445322
Best regards!