ASCII Table — Kotlin 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 Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.
// ASCII Table — pure logic (Kotlin port): the 128-entry ASCII reference table with
// search and range filters.
//
// Language: Kotlin 1.9 — standard library only (kotlin.text / kotlin.collections).
// 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.
*
* @property dec Decimal code point, 0–127.
* @property hex Uppercase hex, e.g. "0x41".
* @property oct Zero-padded 3-digit octal, e.g. "101".
* @property binary Zero-padded 8-bit binary, e.g. "01000001".
* @property char Display glyph: the literal char for printables, a control-picture glyph otherwise.
* @property name Human-readable name, e.g. "Line Feed (LF)", "Uppercase A", "Space".
* @property printable True for 32–126 (visible or space).
* @property control True for 0–31 and 127.
* @property escape C-style escape for control chars that have one (e.g. "\n"); null otherwise.
*/
data class Entry(
val dec: Int,
val hex: String,
val oct: String,
val binary: String,
val char: String,
val name: String,
val printable: Boolean,
val control: Boolean,
val escape: String? = null,
)
/** The `ascii-table` tool's pure logic. */
object AsciiTable {
/**
* Official ASCII control-character names for 0–31 and 127.
*
* Expressed as a `when` over every control code point; the else arm is a
* defensive guard that documents the precondition (the Rust port uses
* unreachable!() for the same case).
*/
private fun controlName(code: Int): String = when (code) {
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)"
// Only called with control codes; defensive guard for misuse.
else -> ""
}
/**
* C-style escape for the control chars that own a standard/common one.
* Returns the literal 2-character source token (backslash + letter), or null.
*/
private fun controlEscape(code: Int): String? = when (code) {
0 -> "\\0"
7 -> "\\a"
8 -> "\\b"
9 -> "\\t"
10 -> "\\n"
11 -> "\\v"
12 -> "\\f"
13 -> "\\r"
27 -> "\\e"
else -> null
}
/**
* Name for a printable punctuation / symbol glyph, or null.
* Letters and digits are derived in [letterName].
*/
private fun symbolName(code: Int): String? = when (code) {
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"
else -> null
}
/** Derive a name for a printable letter or digit. */
private fun letterName(code: Int): String = when {
code in 48..57 -> "Digit ${code - 48}" // '0'..'9'
code in 65..90 -> "Uppercase ${code.toChar()}" // 'A'..'Z'
code in 97..122 -> "Lowercase ${code.toChar()}" // 'a'..'z'
else -> code.toChar().toString()
}
/** Build a single entry from its code point (0–127). */
private fun makeEntry(code: Int): Entry {
val control = code <= 31 || code == 127
// Control-picture glyph: U+2400 for 0–31, U+2421 ("symbol for delete") for DEL.
val char = if (control) {
String(Character.toChars(if (code == 127) 0x2421 else 0x2400 + code))
} else {
code.toChar().toString()
}
val name = when {
control -> controlName(code)
else -> symbolName(code) ?: letterName(code)
}
return Entry(
dec = code,
hex = "0x%02X".format(code),
oct = "%03o".format(code),
binary = code.toString(2).padStart(8, '0'),
char = char,
name = name,
printable = !control,
control = control,
escape = if (control) controlEscape(code) else null,
)
}
/**
* The full 128-entry ASCII table, indexed by code point.
*
* Built once: `by lazy` initializes thread-safely on first access and
* caches for the process lifetime (the Kotlin equivalent of Rust's
* OnceLock). The list is read-only, so sharing it is safe.
*/
val entries: List<Entry> by lazy { (0..127).map { makeEntry(it) } }
/**
* Look up a single entry by code point.
*
* Returns null for out-of-range input. The TypeScript variant returns
* null; Kotlin's nullable type is the idiomatic equivalent, and the type
* system forces callers to handle it.
*/
fun getEntry(code: Int): Entry? = entries.getOrNull(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).
*/
fun filterTable(
query: String = "",
printableOnly: Boolean = false,
min: Int = 0,
max: Int = 127,
): List<Entry> {
val q = query.trim().lowercase()
return entries.filter { e ->
if (printableOnly && !e.printable) return@filter false
if (e.dec < min || e.dec > max) return@filter false
q.isEmpty() || listOf(
e.dec.toString(),
e.hex.lowercase(),
e.oct,
e.binary,
e.name.lowercase(),
e.char.lowercase(),
e.escape.orEmpty(),
).any { it.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 →