ASCII Table — Swift 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 Swift implementation — the same logic the interactive tool runs, in a shareable, citable form.
// ASCII Table — pure logic (Swift port): the 128-entry ASCII reference table with
// search and range filters.
//
// Language: Swift 5.9 — standard library only (no Foundation).
// Source: CosmoDev polyglot showcase port; canonical = src/lib/ascii-table.ts
// + this tool's python.py / rust.rs.
// License: display source — part of CosmoDev's polyglot tool pages.
//
// Each of the 128 ASCII code points is described by its decimal / hex / octal /
// binary forms, a display glyph, a human name, whether it is printable, whether
// it is a control character, and (for control chars that have one) a C-style
// escape sequence.
/// A single ASCII code point and its derived representations.
struct Entry: Equatable {
/// Decimal code point, 0–127.
let dec: Int
/// Uppercase hex, e.g. "0x41".
let hex: String
/// Zero-padded 3-digit octal, e.g. "101".
let oct: String
/// Zero-padded 8-bit binary, e.g. "01000001".
let binary: String
/// Display glyph: the literal char for printables, a control-picture glyph otherwise.
let char: String
/// Human-readable name, e.g. "Line Feed (LF)", "Uppercase A", "Space".
let name: String
/// True for 32–126 (visible or space).
let printable: Bool
/// True for 0–31 and 127.
let control: Bool
/// C-style escape for control chars that have one (e.g. "\\n"); nil otherwise.
let escape: String?
}
/// Namespace for the `ascii-table` tool's pure logic (a caseless enum is the
/// idiomatic un-instantiable namespace in Swift).
enum AsciiTable {
/// Official ASCII control-character names for 0–31 and 127.
///
/// Expressed as a `switch` over every control code point; the default arm
/// is a defensive guard that documents the precondition (Rust's port uses
/// `unreachable!()` for the same case).
private static func controlName(_ code: Int) -> String {
switch code {
case 0: return "Null (NUL)"
case 1: return "Start of Heading (SOH)"
case 2: return "Start of Text (STX)"
case 3: return "End of Text (ETX)"
case 4: return "End of Transmission (EOT)"
case 5: return "Enquiry (ENQ)"
case 6: return "Acknowledge (ACK)"
case 7: return "Bell (BEL)"
case 8: return "Backspace (BS)"
case 9: return "Horizontal Tab (HT)"
case 10: return "Line Feed (LF)"
case 11: return "Vertical Tab (VT)"
case 12: return "Form Feed (FF)"
case 13: return "Carriage Return (CR)"
case 14: return "Shift Out (SO)"
case 15: return "Shift In (SI)"
case 16: return "Data Link Escape (DLE)"
case 17: return "Device Control 1 (DC1)"
case 18: return "Device Control 2 (DC2)"
case 19: return "Device Control 3 (DC3)"
case 20: return "Device Control 4 (DC4)"
case 21: return "Negative Acknowledge (NAK)"
case 22: return "Synchronous Idle (SYN)"
case 23: return "End of Transmission Block (ETB)"
case 24: return "Cancel (CAN)"
case 25: return "End of Medium (EM)"
case 26: return "Substitute (SUB)"
case 27: return "Escape (ESC)"
case 28: return "File Separator (FS)"
case 29: return "Group Separator (GS)"
case 30: return "Record Separator (RS)"
case 31: return "Unit Separator (US)"
case 127: return "Delete (DEL)"
default:
// Only called with control codes; defensive guard for misuse.
return ""
}
}
/// C-style escape for the control chars that own a standard/common one.
/// Returns the literal 2-character source token (backslash + letter), or nil.
private static func controlEscape(_ code: Int) -> String? {
switch code {
case 0: return "\\0"
case 7: return "\\a"
case 8: return "\\b"
case 9: return "\\t"
case 10: return "\\n"
case 11: return "\\v"
case 12: return "\\f"
case 13: return "\\r"
case 27: return "\\e"
default: return nil
}
}
/// Name for a printable punctuation / symbol glyph, or nil.
/// Letters and digits are derived in `letterName(_:)`.
private static func symbolName(_ code: Int) -> String? {
switch code {
case 32: return "Space"
case 33: return "Exclamation mark"
case 34: return "Quotation mark"
case 35: return "Number sign"
case 36: return "Dollar sign"
case 37: return "Percent sign"
case 38: return "Ampersand"
case 39: return "Apostrophe"
case 40: return "Left parenthesis"
case 41: return "Right parenthesis"
case 42: return "Asterisk"
case 43: return "Plus sign"
case 44: return "Comma"
case 45: return "Hyphen / Minus"
case 46: return "Full stop"
case 47: return "Slash"
case 58: return "Colon"
case 59: return "Semicolon"
case 60: return "Less-than sign"
case 61: return "Equals sign"
case 62: return "Greater-than sign"
case 63: return "Question mark"
case 64: return "At sign"
case 91: return "Left bracket"
case 92: return "Backslash"
case 93: return "Right bracket"
case 94: return "Circumflex / Caret"
case 95: return "Underscore"
case 96: return "Grave accent"
case 123: return "Left brace"
case 124: return "Vertical bar"
case 125: return "Right brace"
case 126: return "Tilde"
default: return nil
}
}
/// Derive a name for a printable letter or digit.
private static func letterName(_ code: Int) -> String {
let ch = Unicode.Scalar(code).map(String.init) ?? ""
switch code {
case 48...57: return "Digit \(code - 48)" // '0'..'9'
case 65...90: return "Uppercase \(ch)" // 'A'..'Z'
case 97...122: return "Lowercase \(ch)" // 'a'..'z'
default: return ch
}
}
/// Render `value` in the given radix, zero-padded to `width` digits.
/// (String(format:) would need Foundation; the stdlib has no printf.)
private static func padded(_ value: Int, radix: Int, width: Int, uppercase: Bool = false) -> String {
let digits = String(value, radix: radix, uppercase: uppercase)
return String(repeating: "0", count: max(0, width - digits.count)) + digits
}
/// Trim ASCII/Unicode whitespace from both ends.
/// (String.trimmingCharacters(in:) is a Foundation extension; Character.isWhitespace is stdlib.)
private static func trimmed(_ s: String) -> String {
var view = Substring(s)
while let first = view.first, first.isWhitespace { view = view.dropFirst() }
while let last = view.last, last.isWhitespace { view = view.dropLast() }
return String(view)
}
/// Build a single entry from its code point (0–127).
private static func makeEntry(_ code: Int) -> Entry {
let control = code <= 31 || code == 127
// Control-picture glyph: U+2400 for 0–31, U+2421 ("symbol for delete") for DEL.
// Unicode.Scalar's init is failable — these code points are all valid
// scalars, but we mirror the Rust port's defensive default instead of
// force-unwrapping.
let char = if control {
Unicode.Scalar(code == 127 ? 0x2421 : 0x2400 + code).map(String.init) ?? ""
} else {
Unicode.Scalar(code).map(String.init) ?? ""
}
let name: String
if control {
name = controlName(code)
} else if let symbol = symbolName(code) {
name = symbol
} else {
name = letterName(code)
}
return Entry(
dec: code,
hex: "0x" + padded(code, radix: 16, width: 2, uppercase: true),
oct: padded(code, radix: 8, width: 3),
binary: padded(code, radix: 2, width: 8),
char: char,
name: name,
printable: !control,
control: control,
escape: control ? controlEscape(code) : nil
)
}
/// The full 128-entry ASCII table, indexed by code point.
///
/// Stored as a static let: Swift initializes statics lazily, exactly once,
/// thread-safely — the stdlib equivalent of Rust's `OnceLock`.
static let entries: [Entry] = (0...127).map { makeEntry($0) }
/// Look up a single entry by code point.
///
/// Returns nil for out-of-range input; Swift optionals force callers to
/// handle absence, like Rust's `Option` and the TypeScript variant's null.
static func getEntry(_ code: Int) -> Entry? {
guard (0...127).contains(code) else { return nil }
return entries[code]
}
/// Filter 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).
static func filterTable(query: String = "", printableOnly: Bool = false,
min: Int = 0, max: Int = 127) -> [Entry] {
let q = trimmed(query).lowercased()
return entries.filter { e in
if printableOnly && !e.printable { return false }
if e.dec < min || e.dec > max { return false }
if q.isEmpty { return true }
let haystacks = [
String(e.dec),
e.hex.lowercased(),
e.oct,
e.binary,
e.name.lowercased(),
e.char.lowercased(),
e.escape ?? "",
]
return haystacks.contains { $0.contains(q) }
}
}
}
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 →