crc32demo.gno
1.97 Kb · 65 lines
1// Package crc32demo is a small gnoweb demo of the CRC-32 checksum provided by
2// the [p/moul/x/daily/crc32](/p/moul/x/daily/crc32/v0) library: it checksums a
3// few strings and shows that a one-character change moves the result
4// completely.
5//
6// It contains no checksum logic of its own. Stateless, so Render is
7// deterministic.
8package crc32demo
9
10import (
11 "strings"
12
13 "gno.land/p/moul/x/daily/crc32/v0"
14)
15
16var samples = []string{"", "a", "abc", "123456789", "hello world", "hello worle"}
17
18// Render renders the demo for gnoweb.
19//
20// Render("") / Render("/") -> the samples table
21// Render("/<text>") -> checksum that text
22func Render(path string) string {
23 var b strings.Builder
24 b.WriteString("# CRC-32\n\n")
25 b.WriteString("The IEEE checksum behind zip, gzip and PNG, demoing the ")
26 b.WriteString("[`p/moul/x/daily/crc32`](/p/moul/x/daily/crc32/v0) library.\n\n")
27
28 if in := parseArg(path); in != "" {
29 b.WriteString("## `")
30 b.WriteString(in)
31 b.WriteString("`\n\n`")
32 b.WriteString(crc32.ChecksumHex(in))
33 b.WriteString("`\n")
34 return b.String()
35 }
36
37 b.WriteString("| input | crc32 |\n|---|---|\n")
38 for _, s := range samples {
39 b.WriteString("| ")
40 if s == "" {
41 b.WriteString("_(empty)_")
42 } else {
43 b.WriteString("`" + s + "`")
44 }
45 b.WriteString(" | `")
46 b.WriteString(crc32.ChecksumHex(s))
47 b.WriteString("` |\n")
48 }
49 b.WriteString("\n`123456789` → `cbf43926` is the standard CRC-32 check value, ")
50 b.WriteString("so this table doubles as a conformance test.\n\n")
51 b.WriteString("> The last two rows differ by one letter and share no digits: ")
52 b.WriteString("that avalanche is the point.\n\n")
53 b.WriteString("> A CRC detects **accidents**, not tampering — it is linear, so a ")
54 b.WriteString("matching message is easy to craft. Never authenticate with it.\n")
55 return b.String()
56}
57
58func parseArg(path string) string {
59 s := strings.TrimSpace(path)
60 s = strings.TrimPrefix(s, "/")
61 if i := strings.IndexByte(s, '/'); i >= 0 {
62 s = s[:i]
63 }
64 return s
65}