Skip to content

Hex to String Converter (and String to Hex)

Convert hex to text and text to hex. Paste hex in any shape — spaced, 0x, \x, xxd or hexdump output, Java or C byte arrays — and ASCII, UTF-8, GBK or UTF-16 is detected for you. Runs in your browser.

No Tracking Runs in Browser Free
Conversion runs entirely in your browser — nothing you paste leaves this device.
Try an example

Read as plain hex · 13 bytes

    Text
    Hello, 世界

    Auto-detected UTF-8: every multi-byte sequence is well-formed.

    The same bytes in every encoding

    Encoding Reads as
    UTF-8 Decodes cleanly Hello, 世界
    GBK / GB18030 Decodes cleanly Hello, 涓栫晫
    UTF-16LE Has undecodable bytes 效汬Ɐ隸闧�
    UTF-16BE Has undecodable bytes 䡥汬漬⃤뢖�
    ISO-8859-1 Decodes cleanly Hello, ä¸<96>ç<95><8C>
    The hex dumps, byte arrays and error messages quoted here were captured from real runs of xxd, Python 3.14, Node.js 26, Go 1.27 and clang, and the engine's output formats are tested to read back to the original bytes. Java and PHP behaviour is cited from the official documentation. — Go Tools Engineering · Sep 16, 2026

    Written and reviewed by developers who build the Go Tools encoding utilities. Every hex value and output quoted on this page is produced by the page's own engine and checked by automated tests.

    Hex to ASCII quick answers

    What is 48 65 6C 6C 6F in text?

    Hello 48 is H, 65 is e, 6C is l and 6F is o in ASCII and UTF-8.

    How many bytes is one Chinese character?

    Usually 3 bytes in UTF-8, 2 in GBK 你 is E4 BD A0 in UTF-8 and C4 E3 in GBK.

    What is 0D 0A?

    CR LF (\r\n) Carriage return followed by line feed — the line ending used by Windows, HTTP and most serial command sets.

    What is the letter A in hex?

    41 Lowercase a is 61; the two cases always differ by 20.

    What is hex to string conversion?

    Hexadecimal is a way of writing bytes: each byte, from 0 to 255, is written as two digits from 00 to FF. Hex to string conversion turns those bytes back into readable text, and it always involves a choice of character encoding — the table that says which byte, or sequence of bytes, stands for which character.

    For English text the choice rarely shows, because ASCII, UTF-8, GBK and most other encodings agree on bytes 00 to 7F. It shows immediately with anything else. The bytes C4 E3 BA C3 are 你好 in GBK and invalid in UTF-8, while 你好 in UTF-8 is E4 BD A0 E5 A5 BD. The hex is only half the information; the encoding is the other half.

    String to hex is the reverse: encode the text into bytes, then write each byte as two hex digits. Developers use it to see exactly what goes over a serial line or into a database column, to put binary data into source code, and to compare what two systems actually sent.

    $ echo 48656c6c6f | xxd -r -p
    Hello
    
    >>> bytes.fromhex('c4e3bac3').decode('gbk')
    '你好'
    >>> bytes.fromhex('c4e3bac3').decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte

    What this hex converter does

    Paste hex in any shape

    Spaced, compact, colon- or dash-separated, 0x values, \x escapes, % encoding, C, Go and Java arrays, Java's signed Arrays.toString output, Python bytes literals, Node.js Buffers, and full xxd, hexdump -C and od screens. The page tells you what it recognised and what it removed.

    Encoding detected, with the reason

    Auto-detect checks for a byte-order mark, well-formed UTF-8, UTF-16, pure ASCII and then GBK, and says which rule decided. GBK is only chosen when the bytes read as common Chinese characters, so short binary frames are reported as probably not text instead of as nonsense Chinese.

    Every encoding side by side

    The same bytes are shown as UTF-8, GBK, UTF-16LE, UTF-16BE and ISO-8859-1, each marked as decoding cleanly or not. When text comes out garbled, the correct reading is usually one row down.

    Invisible bytes made visible

    NUL, CR, LF, ESC and other control bytes are shown as ␀ ␍ ␊ ␛, so a trailing 00 or a missing 0D in protocol data stands out. Copying still gives the real characters.

    Output ready to paste into code

    Text → Hex writes spaced or compact hex, 0x lists, \x escapes, a C array in xxd -i style, a Java byte[] with signed values, a Python bytes literal matching repr(), a Go []byte or an xxd dump — and the page can read every one of them back.

    Nothing leaves your browser

    Parsing and decoding run locally in JavaScript. Nothing is uploaded, stored or put in the URL, so packet captures and production logs are safe to paste.

    Hex to string in code

    Python 3

    bytes.fromhex(h).decode()

    bytes.fromhex('48 65 6c 6c 6f').decode('utf-8') returns 'Hello'; spaces between bytes are allowed, a 0x prefix is not. The reverse is s.encode('utf-8').hex(), or .hex(' ') for spaced output. Pass 'gbk' to decode or encode Chinese text in GBK.

    JavaScript (Node.js)

    Buffer.from(h, 'hex')

    Buffer.from(h, 'hex').toString('utf8') decodes, Buffer.from(s, 'utf8').toString('hex') encodes. Invalid input is not an error: decoding stops at the first bad pair and a trailing odd digit is dropped, so validate first.

    JavaScript (browser)

    TextDecoder / TextEncoder

    Parse pairs with parseInt(pair, 16) into a Uint8Array, then new TextDecoder('utf-8').decode(bytes). TextDecoder also reads 'gbk', 'big5' and 'shift_jis', but TextEncoder only produces UTF-8.

    Java 17+

    HexFormat.of()

    new String(HexFormat.of().parseHex(h), StandardCharsets.UTF_8) decodes and HexFormat.of().formatHex(s.getBytes(StandardCharsets.UTF_8)) encodes. On older versions format each byte with String.format("%02x", b); avoid Integer.toHexString(b), which prints ffffffe4 for negative bytes.

    Go

    encoding/hex

    hex.DecodeString(h) returns the bytes and string(b) makes them a string; hex.EncodeToString([]byte(s)) goes back. It is strict: spaces return invalid byte: U+0020 ' ' and an odd length returns odd length hex string.

    C

    sscanf with %2hhx

    Loop over the string two digits at a time into an unsigned char buffer and add a terminating '\0'. To print hex, cast to unsigned char and use %02X, otherwise bytes above 0x7F can print as FFFFFFE4 where char is signed.

    PHP

    hex2bin() / bin2hex()

    hex2bin('48656c6c6f') returns Hello and bin2hex('Hello') returns 48656c6c6f. The manual documents that hex2bin() returns false with an E_WARNING for odd-length or invalid input.

    Shell (xxd)

    xxd -r -p / xxd -p

    echo 48656c6c6f | xxd -r -p prints Hello, and printf 'Hello' | xxd -p prints 48656c6c6f. Use printf rather than echo when encoding, because echo adds a trailing newline, 0a.

    C# (.NET 5+)

    Convert.FromHexString()

    Encoding.UTF8.GetString(Convert.FromHexString(h)) decodes and Convert.ToHexString(Encoding.UTF8.GetBytes(s)) encodes (uppercase, no separators). FromHexString rejects spaces and a 0x prefix. .NET Core and .NET 5+ ship without GBK: call Encoding.RegisterProvider(CodePagesEncodingProvider.Instance) first, then Encoding.GetEncoding(936).

    Hex to string examples

    UTF-8 hex with Chinese characters

    48 65 6C 6C 6F 2C 20 E4 B8 96 E7 95 8C
    Hello, 世界

    The first seven bytes are plain ASCII: 48 65 6C 6C 6F is Hello, 2C is a comma and 20 a space. E4 B8 96 and E7 95 8C are three-byte UTF-8 sequences for 世 and 界 — most Chinese characters take three bytes in UTF-8. Because every sequence is well-formed, auto-detect reads it as UTF-8.

    A GBK sensor reading that is not valid UTF-8

    CE C2 B6 C8 3A 32 35 2E 33 A1 E6
    温度:25.3℃

    Many serial devices send Chinese text in GBK. Here CE C2 is 温 and B6 C8 is 度, 3A 32 35 2E 33 is the ASCII :25.3, and A1 E6 is the full-width ℃ sign — two bytes per Chinese character or symbol. Read as UTF-8 the bytes are invalid (CE starts a two-byte sequence, but C2 is not a continuation byte), and read as GBK they are common characters, so auto-detect picks GBK. A converter that only knows UTF-8 shows replacement characters here.

    xxd output pasted as it is

    00000000: 4869 20e4 bda0 e5a5 bd0d 0a              Hi ........
    Hi 你好␍␊

    This is exactly what printf 'Hi 你好\r\n' | xxd prints. The offset 00000000: and the character column on the right are removed before decoding; if they were read as data, the eight zeros alone would become four NUL bytes at the start. The last two bytes, 0d 0a, are a Windows line break, shown as ␍␊.

    A Java byte array from a log

    [-28, -72, -83, -26, -106, -121]
    中文

    Arrays.toString(bytes) prints Java's signed bytes in decimal. Negative values are bytes of 0x80 and above: -28 is 256 − 28 = 228 = 0xE4. The six bytes E4 B8 AD E6 96 87 are the UTF-8 encoding of 中文.

    Text to hex for a serial AT command

    AT+CSQ\r\n
    41 54 2B 43 53 51 0D 0A

    Modems and most UART command sets expect every command to end in carriage return plus line feed. A text box only produces 0A for Enter, so tick Line breaks as CR LF and the line ending becomes 0D 0A.

    Hex that was hex-encoded twice

    653462646130653561356264
    e4bda0e5a5bd → 你好

    Every byte here is an ASCII hex digit (65 is e, 34 is 4, 62 is b), so the first decode produces another hex string. This happens when a hex string is treated as text and converted again. The page offers the second round, which gives 你好. To avoid false alarms it only offers it when the first result is at least 12 hex digits and the second decodes to real text — dates, timestamps, CRC32 values and MD5 hashes do not trigger it.

    How to convert hex to string

    1. 1

      Paste the hex

      Paste it into the box on the Hex → Text tab in whatever form you have: spaced, compact, 0x values, \x escapes, a byte array or a whole xxd screen. The line under the box says what it was read as.

    2. 2

      Check the text and the encoding

      The text appears on the right, with the auto-detected encoding and the reason for it. If the guess is wrong, the table below shows every reading; pick the right one from the Encoding menu.

    3. 3

      Look for invisible characters

      Control bytes such as NUL, CR and LF are shown as ␀ ␍ ␊. Untick Show invisible characters for the plain text, then copy the result.

    4. 4

      Or convert text to hex

      On the Text → Hex tab, choose the encoding and an output format — spaced hex, 0x values, a C, Java, Python or Go array, or an xxd dump. Tick CR LF for serial and network protocols.

    Why hex to string conversion goes wrong

    Decoding GBK bytes as UTF-8

    Chinese text from older Windows software, many serial devices and legacy databases is GBK. Decoding it as UTF-8 either fails or fills the output with replacement characters. Look at the encoding table and use the reading that makes sense.

    ✗ Wrong
    >>> bytes.fromhex('c4e3bac3').decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte
    ✓ Correct
    >>> bytes.fromhex('c4e3bac3').decode('gbk')
    '你好'

    Using charCodeAt() to get bytes in JavaScript

    charCodeAt() returns a UTF-16 code unit. For ASCII it happens to match the byte, so the bug only appears with other characters, where the result is not what any UTF-8 system sends.

    ✗ Wrong
    '你'.charCodeAt(0).toString(16)   // '4f60' — a UTF-16 code unit
    ✓ Correct
    Buffer.from('你', 'utf8').toString('hex')   // 'e4bda0' — the UTF-8 bytes

    Formatting signed bytes with Integer.toHexString in Java

    Java's byte is signed, so bytes from 0x80 up are negative. Integer.toHexString() works on an int, prints negative values as 32-bit unsigned hex, and drops leading zeros.

    ✗ Wrong
    Integer.toHexString(b)        // "ffffffe4" for 0xE4, "a" for 0x0A
    ✓ Correct
    String.format("%02x", b)      // "e4", "0a"

    Trusting Node.js Buffer.from() with unchecked hex

    Buffer.from(hex, 'hex') never throws. It stops at the first pair that is not valid hex and ignores a trailing odd digit, so a typo gives you a shorter buffer instead of an error.

    ✗ Wrong
    Buffer.from('486', 'hex')      // <Buffer 48> — the 6 is silently dropped
    Buffer.from('48zz65', 'hex')   // <Buffer 48> — stops at zz
    ✓ Correct
    if (!/^([0-9a-f]{2})*$/i.test(hex)) throw new Error('invalid hex');
    Buffer.from(hex, 'hex');

    Pasting a hex dump with its offset column

    A converter that only removes spaces reads the offset 00000000: as data and the character column as more hex where it can. The result starts with NUL bytes and drifts from there. Use xxd -p for plain hex, or paste the dump here, where the columns are recognised.

    ✗ Wrong
    00000000: 4869 20e4 bda0 e5a5 bd0d 0a              Hi ........
    → read naively: 00 00 00 00 48 69 20 e4 …
    ✓ Correct
    $ printf 'Hi 你好\r\n' | xxd -p
    486920e4bda0e5a5bd0d0a

    Sending LF where the device expects CR LF

    AT modems and many line-based protocols end each command with carriage return plus line feed. A command that ends in 0A alone is often ignored with no error at all.

    ✗ Wrong
    41 54 2B 43 53 51 0A      AT+CSQ followed by LF only
    ✓ Correct
    41 54 2B 43 53 51 0D 0A   AT+CSQ followed by CR LF

    When you need a hex to string converter

    Serial and UART debugging
    Serial terminals show received data as hex. Paste a frame to read the text inside it and to spot the 0D 0A or 00 at the end — and go the other way to build a command, with CR LF line endings, that a device will accept.
    Reading packet captures
    Protocol payloads copied from Wireshark or tcpdump are hex. Decoding a request line, a JSON body or a device name inside a frame is quicker here than writing a script, and nothing leaves your machine.
    Byte arrays in application logs
    Java logs byte arrays as signed decimals, Python as b'...' literals and Node.js as <Buffer ...>. Paste the log fragment as it is to see the text, including whether it was UTF-8 or GBK.
    Hex columns and BLOBs in databases
    Database tools show binary columns as hex. Decode a value to check what was actually stored, or convert text to hex to compare byte for byte with what the database holds.
    Strings in firmware and C source
    Embedded code keeps text in byte arrays. Turn a string into a C array ready to paste, or read an array from a header file back as text to confirm what the device will print.

    How hex maps to text: ASCII, UTF-8, GBK and UTF-16

    Two hex digits per byte
    A byte holds 8 bits and one hex digit holds 4, so every byte is exactly two hex digits, 00 to FF, and the number of bytes is always half the number of digits. Upper and lower case mean the same thing. Separators, prefixes and array syntax are only notation: 4865, 48 65, 0x48, 0x65 and \x48\x65 are the same two bytes.
    ASCII: the bytes every encoding agrees on
    ASCII assigns 00 to 7F. Printable characters run from 20 (space) to 7E (~); the rest are control characters, of which 00 (NUL), 09 (tab), 0A (line feed), 0D (carriage return) and 1B (escape) appear most in real data. UTF-8, GBK and ISO-8859-1 all keep these values, which is why plain English survives almost any wrong encoding.
    UTF-8: one to four bytes per character
    UTF-8 writes ASCII as single bytes and every other character as a sequence. The first byte announces the length — C2DF for two bytes, E0EF for three, F0F4 for four — and every following byte must be in 80BF. That strict structure is why a GBK sentence is almost never valid UTF-8 — in our test on 33,910 Chinese sentences, 55 were — and why auto-detect trusts a clean UTF-8 decode. A single Chinese character is different: about 18% of GBK characters happen to form a valid two-byte UTF-8 sequence.
    GBK: two bytes per Chinese character
    GBK keeps ASCII as single bytes and encodes Chinese characters and full-width punctuation as two: a lead byte from 81 to FE followed by a trail byte from 40 to FE, excluding 7F. Because the trail byte range is so wide, short UTF-8 text read as GBK often decodes without any error into unrelated characters — E4 BD A0 E5 A5 BD (你好) becomes 浣犲ソ — which is why this page tries UTF-8 first. GB18030 extends GBK with four-byte sequences for rarer characters; decoding here accepts them.
    UTF-16 and byte order
    UTF-16 uses two bytes per character (four for characters outside the Basic Multilingual Plane), and the two bytes can come in either order. UTF-16LE puts the low byte first — A is 41 00 — and UTF-16BE the high byte first — 00 41. Windows APIs and many files use little-endian and may start with a byte-order mark, FF FE; UTF-8 files sometimes start with EF BB BF. Auto-detect removes a byte-order mark and reports it.

    Converting between hex and strings reliably

    Name the encoding on both ends
    Hex alone does not say which encoding produced it. Wherever text is turned into bytes — getBytes(), encode(), a serial terminal setting, a database connection charset — set the encoding explicitly and write it down next to the hex, so the other side does not have to guess.
    Work with bytes, not character codes
    Functions that return character codes, such as JavaScript's charCodeAt() or Java's char values, give UTF-16 code units rather than encoded bytes. Encode the string first with TextEncoder, Buffer.from() or getBytes(StandardCharsets.UTF_8), then format the bytes.
    Always pad each byte to two digits
    Use %02x or an equivalent, never a bare number-to-hex call. a and 0a look alike in a log, but concatenating unpadded values produces a string with an odd length, or worse, one that decodes into different bytes.
    Keep separators consistent within one log
    Pick one format for logs and traces, such as space-separated pairs, and stick to it. Mixed formats are easy for people to read and easy for scripts to misread, especially when some values are padded and others are not.
    Check the byte count
    Before trusting a conversion, compare the number of bytes with what you expect: the length field in a protocol header, the column size, or the file size. The page shows the count for both directions.

    Hex to string FAQ

    How do I convert hex to a string?
    Paste the hex into the box on the Hex → Text tab; the text appears immediately. By hand it takes two steps. First, split the hex into pairs: each pair of hex digits is one byte, from 00 to FF, so 48656c6c6f is the five bytes 48, 65, 6C, 6C, 6F. Second, decode those bytes with a character encoding. In ASCII and UTF-8, 48 is H, 65 is e, 6C is l and 6F is o, giving Hello. The second step is where results differ: bytes above 7F mean different characters in UTF-8, GBK and other encodings, which is why this page detects the encoding and shows every reading side by side.
    Why does my hex turn into garbled characters?
    Almost always because the bytes are decoded with the wrong encoding. Chinese text is the classic case: C4 E3 BA C3 is 你好 in GBK but invalid UTF-8, and E4 BD A0 E5 A5 BD is 你好 in UTF-8 but turns into 浣犲ソ when read as GBK. Look at the encoding table under the result — the row that reads as sensible text is the encoding the data was written in. With only one or two characters, automatic detection cannot always tell: D2 BB is valid UTF-8 (һ) and also GBK (一), so check the GBK line the page shows under the result. Two other causes are worth ruling out: an extra or missing hex digit, which shifts every following byte by half a byte, and pasting a hex dump with its offset column still attached. If what you have is already garbled text (such as 浣犲ソ) rather than hex, paste the text into the encoding converter instead.
    Serial data looks garbled as text but correct in hex — why?
    If the hex is right, the baud rate, data bits and parity are fine — get those wrong and the bytes themselves change. The problem is the step that turns bytes into characters, and it is usually one of three things. The data may not be text at all: a binary protocol such as Modbus RTU only makes sense as hex. The encoding may not match: a device sends Chinese as UTF-8 while the serial terminal displays GBK, or the other way round, so the UTF-8 bytes E4 BD A0 E5 A5 BD for 你好 show up as 浣犲ソ. Or the text contains control bytes such as 00 or 0D 0A that appear as boxes or line breaks. Paste the hex here: the encoding table shows the UTF-8 and GBK readings side by side, and control bytes appear as ␀ ␍ ␊.
    What is the difference between hex to ASCII and hex to UTF-8?
    ASCII only defines bytes 00 to 7F: letters, digits, punctuation and control characters. UTF-8 is built so that those same bytes mean exactly the same characters, and it uses sequences of bytes from 80 upward for everything else — 2 bytes for accented Latin letters, 3 for most Chinese, Japanese and Korean characters, 4 for emoji. So for plain English text, hex to ASCII and hex to UTF-8 give identical results. They differ as soon as a byte is 80 or higher: an ASCII-only converter cannot show those bytes as characters, while UTF-8 decodes them into the full range of Unicode. For what each byte from 00 to 7F stands for, see the ASCII table.
    How many bytes is a Chinese character in hex?
    It depends on the encoding. In UTF-8 most Chinese characters take 3 bytes: 你 is E4 BD A0. In GBK and GB2312 they take 2 bytes: 你 is C4 E3. In UTF-16 characters in the Basic Multilingual Plane take 2 bytes, and the byte order matters: 你 is 60 4F in UTF-16LE and 4F 60 in UTF-16BE. Rare characters outside that plane take 4 bytes in UTF-8, 4 in UTF-16 (a surrogate pair) and 4 in GB18030. Switch the encoding on the Text → Hex tab to see the byte count for your own text.
    How do I convert hex to a string in Python?
    Use bytes.fromhex() and then decode: bytes.fromhex('48656c6c6f').decode('utf-8') returns 'Hello'. fromhex accepts spaces between bytes, so bytes.fromhex('48 65 6c 6c 6f') works too, but it rejects a 0x prefix with a ValueError. For GBK data decode with 'gbk': bytes.fromhex('c4e3bac3').decode('gbk') returns '你好', while decoding the same bytes as UTF-8 raises UnicodeDecodeError. The reverse is '你好'.encode('utf-8').hex(), which returns 'e4bda0e5a5bd'; pass a separator such as .hex(' ') to get space-separated output.
    How do I convert hex to a string in JavaScript?
    In Node.js, Buffer.from('48656c6c6f', 'hex').toString('utf8') returns 'Hello'. Be careful with bad input: Node does not throw — it stops at the first invalid pair and silently drops a trailing odd digit, so Buffer.from('486', 'hex') is a one-byte buffer. In the browser, build the bytes yourself and use TextDecoder, which also reads GBK: new TextDecoder('gbk').decode(Uint8Array.from('c4e3bac3'.match(/../g), h => parseInt(h, 16))) returns '你好'. Do not use charCodeAt() to get bytes: '你'.charCodeAt(0).toString(16) is '4f60', a UTF-16 code unit, not the UTF-8 bytes e4bda0.
    How do I convert a hex string to a string in C or C++?
    Read two hex digits at a time into an unsigned char buffer, then terminate it: for (size_t i = 0; i < n; i++) sscanf(hex + 2 * i, "%2hhx", &buf[i]); buf[n] = '\0'; where n is strlen(hex) / 2. With hex set to 48656c6c6f2c20e4b896e7958c, printing buf gives Hello, 世界 on a UTF-8 terminal. For the other direction print each byte with printf("%02X ", (unsigned char)s[i]). The cast matters: on platforms where char is signed, a byte such as 0xE4 would otherwise be sign-extended and printed as FFFFFFE4. In C++, append each pair with s.push_back(static_cast<char>(std::stoi(hex.substr(i, 2), nullptr, 16))); the same hex gives Hello, 世界.
    How do I convert hex to a string in Java, and why does it print ffffffe4?
    On Java 17 and later it is one line: new String(HexFormat.of().parseHex(hex), StandardCharsets.UTF_8); for GBK data use Charset.forName("GBK") instead. Going the other way, the classic surprise is ffffffe4. Because Java's byte is signed and Integer.toHexString() takes an int. The byte 0xE4 is stored as -28; widening it to an int keeps the value -28, and toHexString prints negative numbers as the unsigned 32-bit value, ffffffe4. The same method also drops leading zeros, so 0x0A comes out as a. Use String.format("%02x", b), which formats a negative byte as its unsigned 8-bit value, or Integer.toHexString(b & 0xff) with padding. On Java 17 and later, HexFormat.of().formatHex(bytes) converts a whole array, and HexFormat.of().parseHex(hex) goes back.
    Which PHP function converts hex to a string?
    hex2bin() decodes a hex string into a binary string, and bin2hex() goes the other way: bin2hex('Hello') returns 48656c6c6f. According to the PHP manual, hex2bin() returns false and raises an E_WARNING when the input has an odd length or is not valid hexadecimal, so strip spaces and 0x prefixes before calling it. PHP strings are bytes, so the result has whatever encoding the original text used — convert GBK output with mb_convert_encoding() if your page is UTF-8.
    Can I paste xxd or hexdump output directly?
    Yes. The offset column and the character column are recognised and removed, and the line under the input box tells you it happened. This matters because a converter that only strips spaces reads the offsets as data. The page handles xxd (including -u, -c and -g), hexdump -C, Go's hex.Dump, od -A x -t x1 and GNU od -t x1z, and it expands the * line that hexdump and od print in place of repeated rows. It also handles plain hexdump and od -x, which print 16-bit words rather than bytes: on a little-endian machine the bytes 48 69 are printed as 6948, so the page swaps each pair back and uses the last offset to drop the padding byte added to odd-length data. Each xxd, hexdump and od variant was tested against 600 real dumps of random data.
    What does an odd number of hex digits mean?
    Something was lost or added, because every byte is exactly two hex digits. Common causes are a leading zero dropped by a number-to-hex function (a instead of 0a), a character cut off when copying, or a stray letter such as O in place of 0. A hex string produced by converting all the bytes as one big number, such as Python's hex(int.from_bytes(data, 'big')), loses the zero at the start: \r\n comes out as 0xd0a. The page does not guess which digit is missing, because guessing wrong shifts every byte after it by half a byte and produces convincing nonsense. Instead it offers two one-click fixes — add a 0 at the start, or remove the last digit — so you can compare the results. Values written individually with a prefix, such as 0x0 0xa, are fine: each one is read as a whole byte.
    Is the data I paste uploaded anywhere?
    No. The conversion runs in JavaScript in your browser: nothing is sent to a server, stored or added to the page URL. You can confirm it in the Network panel of your browser's developer tools. That matters here, because hex pasted into a converter is often a packet capture, a firmware dump or a line from a production log.

    Related Tools

    View all tools →