ASCII Table — JavaScript 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 JavaScript implementation — the same logic the interactive tool runs, in a shareable, citable form.
// ASCII Table - pure logic (JavaScript port).
//
// CosmoDev polyglot showcase port of the `ascii-table` tool. Ported from
// src/lib/ascii-table.ts. Every output is a pure function of the code point
// 0-127: no React, no DOM, no runtime dependencies. This is the unit-test
// surface shared verbatim with the TypeScript canonical source.
//
// 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.
// Official ASCII control-character names (0-31 and 127).
const CONTROL_NAMES = {
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. Each value is the literal 2-character source token (backslash + letter).
const ESCAPES = {
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).
const SYMBOL_NAMES = {
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',
};
/**
* Derive a name for a printable letter or digit.
*/
function letterName(code) {
if (code >= 48 && code <= 57) return `Digit ${code - 48}`;
if (code >= 65 && code <= 90) return `Uppercase ${String.fromCharCode(code)}`;
if (code >= 97 && code <= 122) return `Lowercase ${String.fromCharCode(code)}`;
return String.fromCharCode(code);
}
/**
* Build a single entry from its code point (0-127).
*/
function makeEntry(code) {
const control = code <= 31 || code === 127;
const printable = !control;
const hex = '0x' + code.toString(16).toUpperCase().padStart(2, '0');
const oct = code.toString(8).padStart(3, '0');
const binary = code.toString(2).padStart(8, '0');
// Control-picture glyph: U+2400 for 0-31, U+2421 ("symbol for delete") for DEL.
const char = control
? (code === 127 ? '␡' : String.fromCharCode(0x2400 + code))
: String.fromCharCode(code);
const name = control ? CONTROL_NAMES[code] : (SYMBOL_NAMES[code] ?? letterName(code));
const escape = control && code in ESCAPES ? ESCAPES[code] : undefined;
return { dec: code, hex, oct, binary, char, name, printable, control, escape };
}
/**
* The full 128-entry ASCII table, indexed by code point.
*/
export const ENTRY = Array.from({ length: 128 }, (_, i) => makeEntry(i));
/**
* Look up a single entry by code point.
* Returns null for out-of-range / non-integer input.
*/
export function getEntry(code) {
if (!Number.isInteger(code) || code < 0 || code > 127) return null;
return ENTRY[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).
*/
export function filterTable(opts = {}) {
const q = (opts.query ?? '').trim().toLowerCase();
const lo = opts.min ?? 0;
const hi = opts.max ?? 127;
return ENTRY.filter((e) => {
if (opts.printableOnly && !e.printable) return false;
if (e.dec < lo || e.dec > hi) return false;
if (q === '') return true;
const hay = [
String(e.dec),
e.hex.toLowerCase(),
e.oct,
e.binary,
e.name.toLowerCase(),
e.char.toLowerCase(),
e.escape ?? '',
];
return hay.some((h) => h.includes(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 →