Hex Encoder and Decoder

Convert text to hex or hex back to text, with a byte dump. Accepts spaced, 0x-prefixed, colon-separated and backslash-escaped forms, because those are what actually get pasted.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Convert. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

An odd digit count

One digit is missing, and front-padding and back-padding give different bytes

68656c6c6

Bytes that are not text

Control bytes mean this is binary, so the text column is a rendering rather than a value

00010203ff

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Assuming the hex length matches the character count

    UTF-8 is variable width: accented Latin is two bytes, most CJK three, emoji four or more. A field with a byte limit rejects input that looks well within a character limit.

    Instead:Count bytes when the limit is in bytes. This page shows both.

  2. Padding an odd number of hex digits

    Some decoders pad the front and some the back, and the two produce completely different bytes. Neither is a safe guess.

    Instead:Find the missing digit. A dropped leading zero from a formatter is the usual cause.

  3. Copying the text column of a binary dump

    If the bytes contain control characters the text is a rendering, not a value, and it will not round-trip.

    Instead:Use the hex, or base64 if you need to move the bytes around as text.

Characters are not bytes, and hex counts bytes

A JavaScript string is UTF-16 and a hex dump is UTF-8. That mismatch is why a character count and a hex length disagree, and it is not an error.

UTF-8 is variable width

ASCII is one byte per character. Accented Latin is two. Most CJK is three. Emoji are four, and longer still once combining marks and skin-tone modifiers are involved. So a ten-character string can be anywhere from ten to forty-odd bytes, and a field with a byte limit rather than a character limit rejects input that looks comfortably within range.

An odd number of digits means one is missing

Every byte is two hex digits. Some decoders pad the front, some pad the back, and the two produce entirely different bytes. Neither is safe to guess at, so this refuses rather than choosing. A dropped leading zero from a formatter that trimmed it is the usual cause.

Hex is not a text encoding

If the bytes contain control characters this is binary: a key, a digest, a signature, a compiled structure. The text column is a rendering rather than a value, and copying it out will not round-trip. Use the hex or the dump, and use base64 if you need to move binary around as text.

The replacement character tells you the encoding is wrong

U+FFFD in the output means a byte sequence could not be decoded as UTF-8. Either the data is not text, or it is text in another encoding, and latin-1 and windows-1252 both produce exactly this. That is the difference between corrupt data and correctly-read data in the wrong encoding, and it is worth knowing which you have before you go looking for the corruption.

The dump is the shape xxd prints

Offset, two groups of eight bytes, then the printable rendering. Reading it is the fastest way to spot a magic number, a length prefix, or padding at the end of a block.

What this cannot see

What the bytes mean. It will not identify a file format, parse a structure, or tell you which encoding non-UTF-8 text is in. It converts and displays, in your browser, with nothing uploaded.