Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

base32demo.gno

2.59 Kb · 88 lines
 1// Package base32demo is a small gnoweb demo of the base32 codec provided by the
 2// [p/moul/x/daily/base32](/p/moul/x/daily/base32/v0) library: it shows the RFC
 3// 4648 vectors alongside Crockford, and the forgiving decodes Crockford allows.
 4//
 5// It contains no codec logic of its own. Stateless, so Render is deterministic.
 6package base32demo
 7
 8import (
 9	"strings"
10
11	"gno.land/p/moul/x/daily/base32/v0"
12)
13
14// The RFC 4648 §10 vectors — every partial-group length.
15var vectors = []string{"", "f", "fo", "foo", "foob", "fooba", "foobar"}
16
17// Render renders the demo for gnoweb.
18//
19//	Render("")       / Render("/") -> the vectors + Crockford forgiveness
20//	Render("/<text>")              -> encode that text both ways
21func Render(path string) string {
22	var b strings.Builder
23	b.WriteString("# Base32\n\n")
24	b.WriteString("RFC 4648 and Crockford, demoing the ")
25	b.WriteString("[`p/moul/x/daily/base32`](/p/moul/x/daily/base32/v0) library.\n\n")
26
27	if in := parseArg(path); in != "" {
28		std, _ := base32.Encode(in)
29		ck, _ := base32.EncodeCrockford(in)
30		b.WriteString("## `")
31		b.WriteString(in)
32		b.WriteString("`\n\n- RFC 4648: `")
33		b.WriteString(std)
34		b.WriteString("`\n- Crockford: `")
35		b.WriteString(ck)
36		b.WriteString("`\n")
37		return b.String()
38	}
39
40	b.WriteString("| input | RFC 4648 | Crockford |\n|---|---|---|\n")
41	for _, v := range vectors {
42		std, _ := base32.Encode(v)
43		ck, _ := base32.EncodeCrockford(v)
44		b.WriteString("| ")
45		if v == "" {
46			b.WriteString("_(empty)_")
47		} else {
48			b.WriteString("`" + v + "`")
49		}
50		b.WriteString(" | `")
51		b.WriteString(std)
52		b.WriteString("` | `")
53		b.WriteString(ck)
54		b.WriteString("` |\n")
55	}
56
57	b.WriteString("\n## Crockford forgives\n\n")
58	enc, _ := base32.EncodeCrockford("hello")
59	b.WriteString("`hello` encodes to `")
60	b.WriteString(enc)
61	b.WriteString("`, and all of these decode back to it:\n\n")
62	variants := []string{enc, strings.ToLower(enc), enc[:2] + "-" + enc[2:]}
63	for _, v := range variants {
64		dec, err := base32.DecodeCrockford(v)
65		b.WriteString("- `")
66		b.WriteString(v)
67		b.WriteString("` → ")
68		if err == nil && dec == "hello" {
69			b.WriteString("`hello` ✅")
70		} else {
71			b.WriteString("❌")
72		}
73		b.WriteString("\n")
74	}
75	b.WriteString("\n> Crockford folds case, reads `I`/`L` as `1` and `O` as `0`, and ")
76	b.WriteString("ignores hyphens — so an identifier survives being read aloud and typed back. ")
77	b.WriteString("`U` is left out of the alphabet on purpose.\n")
78	return b.String()
79}
80
81func parseArg(path string) string {
82	s := strings.TrimSpace(path)
83	s = strings.TrimPrefix(s, "/")
84	if i := strings.IndexByte(s, '/'); i >= 0 {
85		s = s[:i]
86	}
87	return s
88}