ASCII Table — Go source
A searchable, filterable reference for all 128 ASCII code points. See the decimal, hex, octal, and binary form of every character, narrow to printable characters only, clamp the code-point range, and click any row to copy. Runs 100% client-side.
This is the Go implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Package asciitable is the Go twin of CosmoDev's src/lib/ascii-table.ts (dual
// source: the web lib is TypeScript, the CLI lib is Go — kept in lock-step).
// Pure + deterministic, never panics. The table-driven tests in
// ascii-table_test.go share vectors with src/lib/ascii-table.test.ts so the two
// implementations are held to the same contract.
//
// Each of the 128 ASCII code points is described by its decimal / hex / octal /
// binary forms, a display glyph, a human name, printable / control flags, and
// (for control chars that have one) a C-style escape sequence. The table is a
// pure function of the code point (0–127).
package asciitable
import (
"fmt"
"strconv"
"strings"
)
// Entry describes a single ASCII code point (0–127). It mirrors the Entry
// interface in src/lib/ascii-table.ts field-for-field.
type Entry struct {
// Dec is the decimal code point, 0–127.
Dec int
// Hex is the uppercase hex form, e.g. "0x41".
Hex string
// Oct is the zero-padded 3-digit octal form, e.g. "101".
Oct string
// Binary is the zero-padded 8-bit binary form, e.g. "01000001".
Binary string
// Char is the display glyph: the literal char for printables, a
// control-picture glyph for controls.
Char string
// Name is the human-readable name, e.g. "Line Feed (LF)", "Uppercase A".
Name string
// Printable is true for 32–126 (visible or space).
Printable bool
// Control is true for 0–31 and 127.
Control bool
// Escape is the C-style escape for control chars that have one (e.g. "\n"),
// nil otherwise — mirroring the TS lib's optional escape field.
Escape *string
}
// FilterOptions configures FilterTable. It mirrors the filterTable opts object
// in src/lib/ascii-table.ts. The zero value (FilterOptions{}) matches the TS
// default (no query, controls included, full 0–127 range).
//
// Min and Max are *int so the zero value means "default" (Min → 0, Max → 127)
// while an explicit 0 is still honored — exactly like the TS lib's `?? default`.
type FilterOptions struct {
Query string
PrintableOnly bool
Min *int // nil → 0
Max *int // nil → 127
}
// Official ASCII control-character names (0–31 and 127). Mirrors CONTROL_NAMES.
var controlNames = map[int]string{
0: "Null (NUL)",
1: "Start of Heading (SOH)",
2: "Start of Text (STX)",
3: "End of Text (ETX)",
4: "End of Transmission (EOT)",
5: "Enquiry (ENQ)",
6: "Acknowledge (ACK)",
7: "Bell (BEL)",
8: "Backspace (BS)",
9: "Horizontal Tab (HT)",
10: "Line Feed (LF)",
11: "Vertical Tab (VT)",
12: "Form Feed (FF)",
13: "Carriage Return (CR)",
14: "Shift Out (SO)",
15: "Shift In (SI)",
16: "Data Link Escape (DLE)",
17: "Device Control 1 (DC1)",
18: "Device Control 2 (DC2)",
19: "Device Control 3 (DC3)",
20: "Device Control 4 (DC4)",
21: "Negative Acknowledge (NAK)",
22: "Synchronous Idle (SYN)",
23: "End of Transmission Block (ETB)",
24: "Cancel (CAN)",
25: "End of Medium (EM)",
26: "Substitute (SUB)",
27: "Escape (ESC)",
28: "File Separator (FS)",
29: "Group Separator (GS)",
30: "Record Separator (RS)",
31: "Unit Separator (US)",
127: "Delete (DEL)",
}
// C-style escape sequences for the control chars that have a standard/common
// one. Mirrors ESCAPES.
var escapes = map[int]string{
0: "\\0",
7: "\\a",
8: "\\b",
9: "\\t",
10: "\\n",
11: "\\v",
12: "\\f",
13: "\\r",
27: "\\e",
}
// Names for printable punctuation & symbols (letters and digits are derived).
// Mirrors SYMBOL_NAMES.
var symbolNames = map[int]string{
32: "Space",
33: "Exclamation mark",
34: "Quotation mark",
35: "Number sign",
36: "Dollar sign",
37: "Percent sign",
38: "Ampersand",
39: "Apostrophe",
40: "Left parenthesis",
41: "Right parenthesis",
42: "Asterisk",
43: "Plus sign",
44: "Comma",
45: "Hyphen / Minus",
46: "Full stop",
47: "Slash",
58: "Colon",
59: "Semicolon",
60: "Less-than sign",
61: "Equals sign",
62: "Greater-than sign",
63: "Question mark",
64: "At sign",
91: "Left bracket",
92: "Backslash",
93: "Right bracket",
94: "Circumflex / Caret",
95: "Underscore",
96: "Grave accent",
123: "Left brace",
124: "Vertical bar",
125: "Right brace",
126: "Tilde",
}
// letterName derives a name for a printable letter or digit. Mirrors
// letterName() in the TS lib.
func letterName(code int) string {
if code >= 48 && code <= 57 {
return fmt.Sprintf("Digit %d", code-48)
}
if code >= 65 && code <= 90 {
return fmt.Sprintf("Uppercase %c", rune(code))
}
if code >= 97 && code <= 122 {
return fmt.Sprintf("Lowercase %c", rune(code))
}
return string(rune(code))
}
// makeEntry builds a single entry from its code point. Mirrors makeEntry().
func makeEntry(code int) Entry {
control := code <= 31 || code == 127
printable := !control
hex := "0x" + fmt.Sprintf("%02X", code)
oct := fmt.Sprintf("%03o", code)
binary := fmt.Sprintf("%08b", code)
var char string
if control {
if code == 127 {
char = "␡" // U+2421, control picture for DEL
} else {
char = string(rune(0x2400 + code))
}
} else {
char = string(rune(code))
}
var name string
if control {
name = controlNames[code]
} else if n, ok := symbolNames[code]; ok {
name = n
} else {
name = letterName(code)
}
var esc *string
if control {
if v, ok := escapes[code]; ok {
s := v
esc = &s
}
}
return Entry{
Dec: code,
Hex: hex,
Oct: oct,
Binary: binary,
Char: char,
Name: name,
Printable: printable,
Control: control,
Escape: esc,
}
}
// entries is the full 128-entry ASCII table, indexed by code point. Built once
// at package init; mirrors ENTRY in the TS lib.
var entries = func() []Entry {
t := make([]Entry, 128)
for i := range 128 {
t[i] = makeEntry(i)
}
return t
}()
// Table returns the full 128-entry ASCII table, indexed by code point. It is
// the Go twin of ENTRY in src/lib/ascii-table.ts.
func Table() []Entry { return entries }
// GetEntry looks up a single entry by code point. It returns (Entry, false) for
// out-of-range input, mirroring getEntry() returning null in the TS lib. (Go's
// int is always integral, so the TS Number.isInteger check is N/A.)
func GetEntry(code int) (Entry, bool) {
if code < 0 || code > 127 {
return Entry{}, false
}
return entries[code], true
}
// FilterTable filters the table. Query is a case-insensitive substring matched
// against Dec / Hex / Oct / Binary / Name / Char / Escape. PrintableOnly hides
// controls. Min / Max clamp the decimal range (defaults 0–127). It mirrors
// filterTable() in the TS lib.
func FilterTable(opts FilterOptions) []Entry {
q := strings.ToLower(strings.TrimSpace(opts.Query))
lo := 0
if opts.Min != nil {
lo = *opts.Min
}
hi := 127
if opts.Max != nil {
hi = *opts.Max
}
out := make([]Entry, 0)
for _, e := range entries {
if opts.PrintableOnly && !e.Printable {
continue
}
if e.Dec < lo || e.Dec > hi {
continue
}
if q == "" {
out = append(out, e)
continue
}
escapeStr := ""
if e.Escape != nil {
escapeStr = *e.Escape
}
hay := []string{
strconv.Itoa(e.Dec),
strings.ToLower(e.Hex),
e.Oct,
e.Binary,
strings.ToLower(e.Name),
strings.ToLower(e.Char),
escapeStr,
}
for _, h := range hay {
if strings.Contains(h, q) {
out = append(out, e)
break
}
}
}
return out
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →