Skip to content

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 →