Text to hex converter
Convert text to hex — its UTF-8 or UTF-16 bytes, spaced, as an array for code, an escaped string or a dump — and hex back to text in any of those forms.
48 65 6C 6C 6F
A string as the bytes it is stored in
Every string a program handles is a row of bytes underneath, and this page writes them out in hexadecimal, two digits apiece. Type Hello and you get 48 65 6C 6C 6F, one byte per letter with a space after each but the last. Set the direction to Hex to text instead and paste hex from a log, a database or a debugger, and you get back the text those bytes hold.
One text makes different bytes in different encodings, and the Unit decides what the digits on this page are. It starts on UTF-8, the encoding of the web, where H is the byte 48 and א the bytes D7 90. UTF-16 LE and UTF-16 BE spend two bytes on each of them, in opposite orders — 48 00 or 00 48 for H — while Code points leaves bytes out altogether and writes the number Unicode assigns, U+05D0 for א. Whatever Unit is set applies to hex you read as much as to text you write, and it stays set: if pasted hex resembles another Unit’s, the page may suggest that one, but only your click moves it.
Two hex digits to every byte
A byte holds one of 256 values, 0 to 255. Hexadecimal counts in sixteens, with the digits 0 to 9 and then A to F for ten to fifteen, and sixteen sixteens are 256, so two hex digits name every byte and a third is never needed: 00 is 0, 7F is 127 and FF is 255. H is 72, four sixteens and eight, so its byte is 48.
Each hex digit stands for exactly four bits, half a byte: the 4 of 48 is 0100 and the 8 is 1000, and side by side they are the eight bits of H, 01001000. The page keeps both digits of every byte, so a line feed is 0A and a space 20, and because every byte takes the same width, hex can be read back with nothing between the bytes: 4869 is Hi.
Letters in hex mean the same in either case. The page writes capitals unless you choose lowercase, so é is C3 A9 or c3 a9, and it reads both, even mixed in one paste.
Five Styles, each shaped for where it is pasted
In hex, the Style control lays out the same bytes in five ways, each for somewhere hex goes next. For Hi, the two bytes 48 and 69:
- Spaced gives 48 69, a space between bytes: the easiest to read and to count, and the Style the page opens on.
- Compact gives 4869, the digits run together, for a field or a parameter that takes a value as one string of hex.
- Array gives 0x48, 0x69, each byte a number with 0x in front and a comma between, ready to paste into a byte array in C, C#, JavaScript, Python or Go.
- Escaped gives \x48\x69, each byte as \x and its two digits, the way a byte is written inside a C string or a Python bytes literal such as b'\x48\x69'.
- Dump sets the bytes out in lines, with where each line starts and the same bytes as text beside them: the next section reads one.
Reading takes all five back, along with other formatting that leaves the bytes alone: colons as in 48:69, the hyphens .NET’s BitConverter.ToString writes, as in 48-69, 0x or 0X before each byte, and the whole paste wrapped once in round, square or curly brackets or in quotes. The Style and the case matter only for writing, so both controls go away when the direction is Hex to text.
One trap sits in Escaped. In a JavaScript string, or in an ordinary Python string rather than a bytes literal, \x names a character and not a byte, so \xD7\x90 there is two characters and not the א whose UTF-8 bytes are D7 90. Past ASCII, give the bytes to something that takes bytes.
Reading a dump, column by column
A dump sets bytes out sixteen to a line, with a column on each side to help you find them. Written as a Dump, Hello, World! and a line feed fill one line: first 00000000, the offset, which is where the line’s first byte stands counted from zero, in eight hex digits; then the fourteen bytes, eight and then six with a wider gap between the halves; then |Hello, World!.|, the same bytes as characters, every byte that is not printable ASCII shown as a dot, the line feed among them. A last line holds only 0000000E, which is fourteen: where the next byte would stand, and so the length. That is the layout hexdump -C prints.
- With Hex to text chosen and any Unit but Code points, a pasted dump is read for its bytes alone: the text column is left out of the reading, no offset is read as a byte, and a note below the result says the input was taken as a dump and names the layout.
- Two layouts are read that way: hexdump -C’s, and what xxd prints with no options, where a colon follows each offset and the bytes stand in groups of four digits. The plain hex that xxd -p prints needs no layout and reads like any other hex.
- hexdump -C prints a line of just * in place of lines that repeat the one above, and the page fills those lines back in from the offset below, so the bytes come back complete.
- Each offset after the first must follow from the bytes above it, the length on hexdump -C’s last line among them, and a line whose offset does not is refused there rather than read wrong: that is where a line left out, a byte lost or an offset mistyped shows. What no offset comes after cannot be checked, so a dump missing its first lines, or the end of one with no length line after it, as xxd writes none, reads as whatever is left.
UTF-16 LE, and why every second byte is 00
Windows keeps text in UTF-16 with the low byte first, which is UTF-16 LE; in .NET it is Encoding.Unicode, and SQL Server stores an NVARCHAR value the same way. UTF-16 gives each character up to U+FFFF two bytes, and for anything up to U+00FF — the English letters, the digits, é and the rest of Latin-1 — the high byte is 00. With the low byte first, that zero lands after each letter: Hi is 48 00 69 00.
SQL Server shows a VARBINARY value as 0x and its hex, so an NVARCHAR holding Hi, cast to VARBINARY, shows as 0x48006900. Paste that here while UTF-8 is chosen and the text comes out as H, a NUL, i and a NUL, and the note under it says every second byte is 00, as it is when Latin text is written in UTF-16 rather than UTF-8, with Switch to UTF-16 LE beside it. Press that and the same bytes read Hi.
UTF-16 BE puts the high byte first instead, so Hi is 00 48 00 69 there, and א, D0 05 in UTF-16 LE, is 05 D0. Zeros in the first place of each pair make the note offer UTF-16 BE. It says nothing once a character past U+00FF is in the text, because that character’s high byte is not 00, and it speaks only where every second byte is.
A byte-order mark at the start
A text can begin with U+FEFF, a character that shows nothing and is there to be a byte-order mark. In UTF-16 its two bytes give the order of every pair after them, FF FE for UTF-16 LE and FE FF for UTF-16 BE, and in UTF-8 it is the three bytes EF BB BF, a signature that the text is UTF-8, which has only one order.
The page keeps a mark rather than dropping it. Hex that opens with the chosen Unit’s own mark reads as a text beginning with U+FEFF, and a note says the mark was kept, so writing that text again gives the same bytes, mark included. Hex that opens with the mark of the other UTF-16 order, or with a UTF-16 mark while UTF-8 is chosen, gets a note that the bytes open with another Unit’s mark, beside a switch to the order the mark names. Anywhere after the start, U+FEFF is an ordinary character and draws no note.
Bytes that are no text, shown as U+FFFD
Not every sequence of bytes is text in the chosen Unit: a character missing its last byte, a stray byte such as E9, which older code pages write for é, and an odd byte left at the end of UTF-16 all spell nothing. One bad sequence does not sink the paste, though: each is swapped for U+FFFD, the replacement character, and everything else reads normally.
A note then gives their number and names the first by its place among the bytes, by the digits you wrote for it and by its line and column. Café saved in Windows-1252, the Windows code page for Western European text, is 43 61 66 E9, é being the one byte E9 there; read as UTF-8 it comes back as Caf and U+FFFD, and the note names byte 4, written E9, at line 1, column 10. In UTF-8 the word is 43 61 66 C3 A9.
It counts sequences, not bytes: F0 9F 98, three of the four bytes of 😀, are one U+FFFD. And a U+FFFD that really is in the text, the bytes EF BF BD, is read as text and not counted at all, so the note is only ever about bytes that did not read.
Turning hex back into a file
Reading hands over the bytes as well as the text. With the direction on Hex to text and UTF-8, UTF-16 LE or UTF-16 BE chosen, Download saves, as a file named bytes.bin, exactly the bytes that were read, the ones that were not text among them and before any was replaced: the job xxd -r does with a dump. There is no Download for code points, which are not bytes, nor while writing, when what you take away is digits.
So hex of something that was never text still comes back whole. Every PNG image starts with the eight bytes 89 50 4E 47 0D 0A 1A 0A; read as UTF-8 they show as U+FFFD, the letters PNG and four control characters, with a note about the one sequence that is not text, and Download saves all eight exactly. The file is always called bytes.bin, since bytes carry no name, so give it its own, such as image.png, once it is saved.
Where to go for a character, its bits or a number
For what a character is — its name, its category, and whether it is one of the invisible ones — the Unicode character inspector takes a text apart one code point at a time and shows the UTF-8 bytes of each as well.
The Text to binary converter is this same page opening on binary, where the pattern UTF-8 follows can be read in the first bits of every byte. And a number is not a text: 255 entered here is the digits 2, 5 and 5, and so the bytes 32 35 35, while the Number base converter takes 255 as a quantity and writes it in hex as ff.
Frequently asked questions
- How do I turn hex into text?
- Choose Hex to text, paste the hex, and set the Unit to match the encoding it was written in: UTF-8 for most text, UTF-16 LE for hex taken from a Windows or .NET string or an NVARCHAR column. Spaces, commas, colons and hyphens between the bytes, 0x or \x in front of them and one wrapper around the whole are read through, and so is either case.
- Why is there a NUL between every letter of my text?
- The hex is most likely UTF-16 LE read as UTF-8. UTF-16 LE writes each English letter as two bytes, its ASCII value and then 00, and UTF-8 reads each of those zeros as a character of its own, NUL. Choose UTF-16 LE, or press the switch if the page offers it beside its note, and the letters close up.
- Why do accented letters in my hex come out as U+FFFD?
- Most likely the hex was written in an older code page such as Windows-1252, where é is the one byte E9, while in UTF-8 é is C3 A9 and a lone E9 is not text. The page reads UTF-8 and UTF-16 and no older code page, so instead of guessing which one was meant it shows each such sequence as U+FFFD and says where the first one is. Download still gives you the bytes as they were.
- Can I paste what xxd or hexdump -C printed?
- Yes: hexdump -C’s layout, which is also what the Dump Style writes, and what xxd prints with no options. The text column is set aside and no offset is read as a byte, a * line is filled back in, and a note says which of the two layouts was read; an offset that does not follow from the bytes before it stops the reading at its line, since the lines no longer agree with each other. The plain hex of xxd -p is read as well, like any other hex, with no note.
- Does it matter whether hex is uppercase or lowercase?
- Not to the bytes: 4A and 4a are the same byte, J. The page writes capitals unless you choose lowercase, and that choice covers a Dump’s offsets as well as its bytes; reading takes either, even mixed within one paste.
- How do I get a file back from a hex dump?
- Choose Hex to text and UTF-8 or either UTF-16, paste the dump or the plain hex, and press Download. The file it saves, bytes.bin, holds exactly the bytes read from what you pasted, text or not, so it does the job of xxd -r; rename it to what it was.
- Is it safe to paste hex from a production database or a log?
- Yes, as far as the conversion goes. It happens on your own device, whichever way it runs: the hex you paste, the text it becomes and any file Download saves are never sent anywhere.
Related tools
- Text to binary converter
Binary writes a byte as its eight bits, which is where UTF-8’s pattern can be read: é is C3 A9 here and 11000011 10101001 there, the first byte opening 110 because the letter takes two and the second 10 because it continues it. This page offers binary too; that page opens on it.
- Unicode character inspector
See exactly which characters a string is made of.
- Number base converter
Type 255 on this page and you get three bytes, one for each of its characters: 32 35 35. That page reads 255 as a number instead and converts the value itself, which in hex is ff.
- Base64
Encode and decode Base64 — full UTF-8 support.