§

Options

Mode
Hex grouping
0x prefix
Case
Text encoding
§

Input

§

Output

US incident responders working ICS-CERT cases lean on hex ↔ ASCII conversion every time they pull a packet capture into Wireshark and inspect the byte pane of a Modbus or DNP3 frame, since protocol headers read cleanly in hex while payloads often hide ASCII text inside binary framing. UK NCSC CHECK assessors auditing HMG IA Standard No.1 evidence packs flip between hex and ASCII when reviewing cryptographic material exchanged with HSMs, since session keys ship as hex strings but vendor-specific tag bytes embed plain ASCII labels. Embedded firmware engineers on both sides of the Atlantic read JTAG dumps the same way, and this converter handles the same translation without leaving the browser tab.

How hex encoding works

Every character on a page is stored as one or more bytes. Hex encoding rewrites those bytes in base 16, two characters per byte, so the byte stream is readable without special tools.

  1. Encode the text into bytes. UTF-8 mode runs the input through new TextEncoder().encode(text), which returns a Uint8Array of byte values. Latin-1 mode takes the low eight bits of each code unit via charCodeAt(0) & 0xFF, which is the conversion the legacy ISO-8859-1 codecs perform.
  2. Render each byte as two hex digits. Each byte maps to two hex digits via byte.toString(16).padStart(2, "0"). The case toggle picks uppercase (A-F) or lowercase (a-f) on the output letters.
  3. Apply grouping and prefix. Grouping inserts a separator between bytes: a single space, a dash, or a space every four bytes. The 0x prefix can be prepended once to the whole string (None grouping) or per byte (Space grouping), matching the conventions C arrays and binary diff tools expect.
  4. Decode in reverse. Hex → Text mode strips every space, dash, and 0x prefix from the input, validates the remaining characters against /^[0-9a-fA-F]+$/, rejects odd-length strings, and rebuilds a Uint8Array from successive byte pairs. UTF-8 mode decodes that array with new TextDecoder("utf-8", { fatal: true }); Latin-1 mode maps each byte to String.fromCharCode(b).
  5. Live mode for fast iteration. Live mode is on by default. Every keystroke schedules a 150 ms debounced re-convert so you can paste, edit, and watch the other pane update without clicking the Convert button.

Why use a hex converter

  • Debugging binary protocols. Wire formats like Modbus, DNP3, and CoAP pack their headers into specific byte offsets. Reading a captured frame as hex shows each field at a glance, and flipping the same bytes back to ASCII surfaces any plaintext payload sitting alongside the binary framing.
  • Working with embedded firmware. JTAG and SWD probes report memory contents as hex. Translating a region of memory into ASCII spots embedded strings (file paths, error messages, vendor signatures) that often pinpoint where in the firmware you are looking.
  • Reading packet captures. Wireshark and tcpdump both ship a byte pane that prints each packet as hex on the left and ASCII on the right. Converting a snippet here lets you copy a hex blob out of a bug report or a chat log and read what the bytes actually say without re-importing them into a capture tool.
  • Byte-level diffs. Comparing two binary files often comes down to spotting which bytes changed. Converting both sides to hex with a consistent grouping makes the diff line up in a text editor, where a built-in diff tool can highlight the changed bytes.

Common applications

Hex ↔ ASCII conversion shows up across reverse engineering, security, and embedded work whenever a byte stream is more than just a text payload.

  • Reverse engineering: take a hex dump from a strings-resistant binary, pick out runs that decode as printable ASCII, and use those strings to anchor where you are in the disassembly.
  • Network forensics: copy a single packet payload out of Wireshark as hex, paste it here, and read the application-layer text without exporting the whole capture.
  • Crypto material handling: a key, IV, or HMAC tag often ships as a hex string. Decoding back to bytes confirms the length matches the algorithm (16 bytes for AES-128, 32 for AES-256) before you wire it into a config.

A worked example

Pick Text → Hex, UTF-8, lowercase, Space-every-byte grouping, prefix off. Type Hi: the output reads 48 69. Switch the prefix on and the grouping to None and the same input renders as 0x4869. Paste the emoji 😀 as input and UTF-8 mode renders f0 9f 98 80 — four bytes for one code point, which is why emoji often inflate transmission size. Switch to Hex → Text and paste 0x48-65-6C 6C 6F: the parser strips the prefix, the dashes, and the spaces and rebuilds Hello.

FAQ

What is hex encoding?

Hex encoding (or hexadecimal encoding) writes a byte stream in base 16, two ASCII characters per byte. Each hex digit covers four bits, so two digits cover one eight-bit byte. The alphabet runs 0-9 then A-F (or a-f); the case is purely a presentation choice and decoders accept either. Hex is the standard way to write raw bytes in protocol specs, debugger output, and crypto keys because it is twice as compact as binary and avoids the unprintable-character problems of raw bytes in text.

Why does my emoji become 4 bytes in hex?

UTF-8 is a variable-length encoding. ASCII characters (U+0000 to U+007F) take one byte, Latin-1 supplements take two, most other BMP code points take three, and characters above U+FFFF — including most emoji — take four. The smiling face 😀 is U+1F600 and encodes to F0 9F 98 80. If you need a fixed-width byte view, switch to Latin-1 — but Latin-1 only covers the first 256 code points, so any character outside that range cannot round-trip.

Does this support Latin-1 / ISO-8859-1?

Yes. Switch the Text encoding option to Latin-1 (ISO-8859-1). Encoding takes the low eight bits of each JavaScript code unit (charCodeAt(0) & 0xFF), which matches the legacy single-byte mapping. Decoding uses String.fromCharCode(byte) for each byte. Use Latin-1 when you are working with output from older Windows-1252 or pre-Unicode systems where each byte stands for exactly one character.

Is the conversion done in my browser?

Yes. The converter runs TextEncoder, TextDecoder, and a small parser as a single static page. There is no upload, no API call, and no analytics on what you paste — only the standard page-load metrics shared across the site. The same hex bytes you see here are what a Node script or a Lambda function would produce against the same input.

Hex ↔ ASCII conversion is a small job that anyone reading binary protocols or embedded firmware does several times a day. Doing it in a browser tab, with the same native encoders Node and V8 already ship, keeps the work fast and the byte stream on your machine.