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.
- Encode the text into bytes. UTF-8 mode runs the input through
new TextEncoder().encode(text), which returns aUint8Arrayof byte values. Latin-1 mode takes the low eight bits of each code unit viacharCodeAt(0) & 0xFF, which is the conversion the legacy ISO-8859-1 codecs perform. - 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. - 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.
- Decode in reverse. Hex → Text mode strips every space, dash, and
0xprefix from the input, validates the remaining characters against/^[0-9a-fA-F]+$/, rejects odd-length strings, and rebuilds aUint8Arrayfrom successive byte pairs. UTF-8 mode decodes that array withnew TextDecoder("utf-8", { fatal: true }); Latin-1 mode maps each byte toString.fromCharCode(b). - 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.