hexdump -ve '1/1 "%02x"'
xxd -p | tr -d '\n'

If you get tired of writing this every time, create an alias.

Answer from grawity on Stack Exchange
🌐
SysTutorials
systutorials.com › convert-hex-to-ascii-using-xxd
Converting Hex To ASCII With Xxd - SysTutorials
April 12, 2026 - Not all hex represents text. If your data contains null bytes or non-printable characters, xxd -r -p handles them correctly — you just won’t see them in terminal output:
🌐
Rob Allen
akrabat.com › use-xxd-to-convert-to-hex
Use xxd to convert to hex – Rob Allen
July 23, 2024 - $ xxd foo.txt 00000000: 5468 6973 2069 7320 736f 6d65 2074 6578 This is some tex 00000010: 7421 0a t!. ... ASCII representation, with a . for escape characters, like the 0A on the second line · There are some options that I find useful. Firstly, we can use -u to get uppercase hex letters which I find more “normal”.
Discussions

hexdump - Parsing Hex dump - Stack Overflow
I recently came across a kaitai struct to deal with arbitrary binary formats. Now the thing is I have a hex-dump what I mean by that is I have a file which i want to parse and its in hex format whe... More on stackoverflow.com
🌐 stackoverflow.com
c - Transform hexadecimal information to binary using a Linux command - Stack Overflow
I have this binary file on my Linux system... udit@udit-Dabba ~ $ cat file.enc Salted__s�bO�� More on stackoverflow.com
🌐 stackoverflow.com
bash - Can xxd be used to output the binary representation of hex number , not a string? - Unix & Linux Stack Exchange
I would like to generate a raw binary packet from hex in the command line for the purpose of testing a protocol. I'm hoping its simpler to do it this way than writing an aplication. Here is what More on unix.stackexchange.com
🌐 unix.stackexchange.com
bash - Decode a base64 string and encode it as hex using xxd - Stack Overflow
xxd -p may have \n chars in the output so you need to remove them: Copybase64_to_hex() { echo "$1" | base64 --decode | xxd -p | tr -d '\n' } More on stackoverflow.com
🌐 stackoverflow.com
People also ask

How do I decode hex to UTF-8 or ASCII correctly?
Decode the bytes first, then interpret them with the charset that matches the source system. ASCII works for simple byte dumps, while UTF-8 is usually the right choice for modern text. If accents or symbols look wrong, try Latin-1 or Windows-1252.
🌐
encode64.com
encode64.com › home › encoding decoding › hex decoder
Hex Decoder Online | Convert Hex to Text | Encode64
Why does my hex string fail to decode?
The most common causes are invalid characters, an odd number of hex digits, or mixed formatting that does not match the enabled input rules. Check whether the source uses plain hex, spaced bytes, 0x tokens, or escapes before retrying.
🌐
encode64.com
encode64.com › home › encoding decoding › hex decoder
Hex Decoder Online | Convert Hex to Text | Encode64
Can I decode odd-length hex?
You can, but it depends on the parsing rule you choose. In most debugging workflows, odd-length hex means a nibble is missing or the value was truncated, so failing fast is usually safer than padding automatically.
🌐
encode64.com
encode64.com › home › encoding decoding › hex decoder
Hex Decoder Online | Convert Hex to Text | Encode64
🌐
GitHub
gist.github.com › mzpqnxow › a23e0e3621e778dada9c4bb96ab02ff1
Ingesting ASCII hex dumps into Python strings · GitHub
Ingesting ASCII hex dumps into Python strings · Raw · import_od_xxd.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Top answer
1 of 3
30
hexdump -ve '1/1 "%02x"'
xxd -p | tr -d '\n'

If you get tired of writing this every time, create an alias.

2 of 3
11

How to easily convert to/from plain machine-readable hexadecimal data

In brief.

$ xxd -plain test.txt > test.hex
$ xxd -plain -revert test.hex test2.txt
$ diff test.txt test2.txt
$

Explanation:

$ xxd -plain test.txt > test.hex

This writes a hex encoding of the data in test.txt into new file test.hex. The -p or -plain option makes xxd use "plain" hex format with no spaces between pairs of hex digits (i.e. no spaces between byte values). This converts "abc ABC" to "61626320414243". Without the -p it would convert the text to a 16-bit word oriented traditional hexdump format, which is arguably easier to read but less compact and therefore less suitable as a transmission format and slightly harder to reverse.

$ xxd -plain -revert text.hex test2.txt

This uses the -r or -revert option for reverse operation. The -plain option is used again to indicate that the input hex file is in plain format.

I make the output filename different from the original filename so we can later compare the results with the original file.

$ diff test.txt test2.txt
$ 

The diff command outputs nothing - this means there is no difference between the original and reconstituted file contents.


I'm tired of digging of some special format strings

Use alias or declare functions in your .profile to create mnemonics so you don't have to remember or dig about in man pages.

or just remember -plain and -revert.


Wrapped output

Yes, there are new-line characters in the output. You want to avoid that. You can use the -c or -cols option to specify how long you want the output lines to be to attempt to avoid line-wrapping of the output. -c 0 gives the default length and the man page suggests 256 is the limit but it seems to work beyond that.

$ xxd -plain -cols 9999 test.txt > test.hex
$ wc test.txt test.hex
  121   880  4603 test.txt
    1     1  9207 test.hex

The wc wordcount command tells us how many lines, words and characters are in each file.

So 121 lines (880 words, 4603 bytes) of ASCII text were encoded as 1 line of hex digits.

🌐
cheat.sh
cheat.sh › xxd
cheat.sh/xxd
# More information: <https://manned.org/xxd>. # Generate a hexdump from a binary file and display the output: xxd input_file # Generate a hexdump from a binary file and save it as a text file: xxd input_file output_file # Display a more compact output, replacing consecutive zeros (if any) with a star: xxd -a input_file # Display the output with 10 columns of one octet (byte) each: xxd -c 10 input_file # Display output only up to a length of 32 bytes: xxd -l 32 input_file # Display the output in plain mode, without any gaps between the columns: xxd -p input_file # Revert a plaintext hexdump back into binary, and save it as a binary file: xxd -r -p input_file output_file $ Follow @igor_chubin cheat.sh
Find elsewhere
🌐
ConvertString
convertstring.com › EncodeDecode › HexDecode
Hex to Text - Online Hex Decoder
Convert hex to text and hex decode strings. Online tool for hex decoding a string. Convert a hexadecimaly encoded text into an decoded string or download as a file using this free online hex to text decoder utility. Hex to text, Hex to file download.
🌐
Encode64
encode64.com › home › encoding decoding › hex decoder
Hex Decoder Online | Convert Hex to Text | Encode64
If the decoded output looks wrong, do not assume the hex is invalid. The bytes may simply require a different character set. ... For automation, CI, or sensitive data, prefer command-line decoding with xxd, Python, Node.js, or PowerShell.
🌐
daily.dev
daily.dev › home › john hammond › decode hex on linux
Decode Hex on Linux | daily.dev
October 19, 2024 - The process involves piping standard input into xxd and using various flags like '-p' for printing and '-r -p' for reversing and decoding hexadecimal strings.
🌐
Hardmath123
hardmath123.github.io › binarystrings.html
Notes on Binary Strings - Comfortably Numbered
November 13, 2014 - The pattern hex(number).decode('hex') is quite common (for example, in RSA problems). Keep in mind that you need to strip the leading 0x and possibly a trailing L from the output of hex, and also make sure to pad with a leading 0 if there are an odd number of characters. Finally, Python handles base64 with the base64 module, but you can also just use str.encode('base64') and str.decode('base64').
Top answer
1 of 3
15

echo '0A' produces three characters: 0 A NL; xxd -b will then print those three characters in binary. If you wanted just the single byte whose value is 10 (i.e. hexadecimal A), you could write (in bash):

echo -n $'\x0A'
      ^ ^  ^
      | |  |
      | |  +-- `\x` indicates a hexadecimal escape
      | +----- Inside a $' string, escapes are interpreted
      +------- -n suppresses the trailing newline

A better alternative would be printf '\x0A'; printf interprets escape sequences in the format string, and does not output implicit newlines. (For a completely Posix-compatible solution, you would need an octal escape: printf '\012'. printf should work on any Posix-compatible shell but hexadecimal escapes are an extension.) Yet another bash possibility is echo -n -e '\x0A'; the (non-standard) -e flag asks echo to interpret escape sequences.

echo '0A' | xxd -b won't output the equivalent of hex 0A, because xxd doesn't know that you intend 0A to be a hex number rather than two characters. It just takes its input as a series of characters, regardless of what those characters are.

Endianness does not affect bytes. The order of bits inside a byte is entirely conceptual until the byte is transmitted over a serial line and even then it is only visible with an oscilloscope or something similar.

2 of 3
8

If you want the binary output for a string of hex digits, xxd -r -p. E.g.:

 $ echo '0A0B0C0D' | xxd -r -p | xxd -b
 0000000: 00001010 00001011 00001100 00001101                    ....

converts 0A0B0C0D into a four bytes of binary (first call to xxd), and then converts it back to be printable (second call). You say you want a binary output, but the examples you're trying for are a printable representation.

I don't know of anything where endianness is ambiguous at the nibble level, as you imply in your second example. The conversion in xxd is a pure byte at a time, not assuming they represent any particular multi-byte number.

🌐
Man Pages
manpages.org › xxd
man xxd (1): make a hexdump or do the reverse.
xxd creates a hex dump of a given file or standard input. It can also convert a hex dump back to its original binary form. Like uuencode(1) and uudecode(1) it allows the transmission of binary data in a `mail-safe' ASCII representation, but has the advantage of decoding to standard output.
🌐
Linux Journal
linuxjournal.com › content › doing-reverse-hex-dump
Doing a Reverse Hex Dump | Linux Journal
June 2, 2008 - You can use xxd to dump binary files just like hexdump and od, but you can also use it to do the reverse: turn a hex dump back into binary.
🌐
Hexmos
hexmos.com › freedevtools › c › cmd › xxd
Xxd - Hex Dump Utility for Data Conversion Cheatsheet | cmd Reference | Online Free DevTools
Conversely, xxd can also reverse this process, taking a hexadecimal string and converting it back into its original binary or text form. This is crucial for decoding data that has been encoded in hexadecimal.
🌐
Computer Hope
computerhope.com › unix › xxd.htm
Linux Xxd Command
June 1, 2025 - The xxd program takes a file or standard input and outputs a hex dump that uses only ASCII or EBCDIC (Extended Binary Coded Decimal Interchange Code) characters. This output hex dump can be safely emailed and reconstructed at the destination.
Top answer
1 of 2
4

Convert small base64 encoded string to hexadecimal

1. Reducing forks

Accepted answer do offer a solution with a lot of forks! I hate useless forks!

There is my short base64 to hexadecimal converter:

b64toHex() {
    local _arLines
    mapfile -t _arLines < <(base64 -d <<< "$2" | xxd -p)
    printf -v "${1:-hexString}" %s "${_arLines[@]}"
}

In order to avoid fork like myVar=$(myFunc args), this function will only populate a variable and won't print out anything.

b64toHex myVar "OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw="
echo $myVar
3906dbf2b5e78ff0f0be0956d35f2e3ffd6daa577088931b8f10615fb66ac13c

Then you could use:

b64toHex iv_hex "${iv}"
b64toHex key_hex "${key}"

See at bottom of this for execution time comparison.

2. Pure bash way:

This don't depend on xxd or base64 to be installed. (And without forks, will be significantly quicker than running 3 forks! Keep in mind, if you plan to run this repetitively!)

From this: Bash script - decode encoded string to byte array, on my website: base64decoder.sh.txt, base64decoder.sh, with a very small modification**:

**At line 41:
- ((_ar==0)) && printf -v _res %b "${_res[@]/#/\\x}"
+ ((_ar==0)) && printf -v _res %s "${_res[@]}"

First prepare a read-only array as:

declare -a B64=( {A..Z} {a..z} {0..9} + / '=' )
declare -Ai 'B64R=()'
for i in "${!B64[@]}"; do B64R["${B64[i]}"]=i%64; done
declare -r B64R
unset B64

Then b64ToHex function:

b64ToHex() {
    local _4B _Tail _hVal _v _opt OPTIND
    local -i iFd _24b _ar
    while getopts "av:" _opt; do case $_opt in
        a) _ar=1;; v) _v=${OPTARG};; *) return 1;; esac; done
    shift $((OPTIND-1))
    if [[ $_v ]];then local -n _res=${_v}; else local _res; fi
    if [[ $1 ]]; then    exec {iFd}<<<"$1"          # Open Input FD from string
    else                 exec {iFd}<&0        ; fi  # Open Input FD from STDIN
    _res=()
    while read -rn4 -u $iFd _4B; do
        if [[ "$_4B" ]]; then
            _Tail=$_4B
            _24b=" B64R['${_4B::1}'] << 18 | B64R['${_4B:1:1}'] << 12 |
                   B64R['${_4B:2:1}'] << 6 | B64R['${_4B:3:1}'] "
            printf -v _hval %02x\  $((_24b>>16)) $((_24b>>8&255)) $((_24b&255))
            read -ra _hval <<<"$_hval"
            _res+=("${_hval[@]}")
        fi
    done
    exec {iFd}<&-
    _Tail=${_Tail##*([^=])}
    while [[ $_Tail ]]; do
        unset "_res[-1]"
        _Tail=${_Tail:1}
    done
    ((_ar==0)) && printf -v _res %s "${_res[@]}" && _res=("${_res[0]}")
    [[ -z $_v ]] && echo "${_res[@]}"
}

If bash loop are known to be slow, doing a loop over only 32 byte will be significantly quicker and less system expansive than running four forks!

Usage from STDIN:

b64ToHex <<<"OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw="
3906dbf2b5e78ff0f0be0956d35f2e3ffd6daa577088931b8f10615fb66ac13c

From an argument:

b64ToHex "OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw="
3906dbf2b5e78ff0f0be0956d35f2e3ffd6daa577088931b8f10615fb66ac13c

Assign a variable:

b64ToHex -v someVar "OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw="
echo "$someVar"
3906dbf2b5e78ff0f0be0956d35f2e3ffd6daa577088931b8f10615fb66ac13c

Then from, to variables:

b64ToHex -v iv_hex "${iv}"
b64ToHex -v key_hex "${key}"

Note: this is done without any fork.

For fun: retrieving original base64 string, with bash V5.1+, you could:

shopt -s extglob
printf %b ${someVar//??/\\x& } | base64
OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw=

3. Pure bash way, but usign bash V5.2+

Same script, but by using patsub_replacement and mapfile, I could do this without any bash loop!

declare -a B64=( {A..Z} {a..z} {0..9} + / '=' )
printf -v _b64_tstr '["\44{B64[%d]}"]=%%d%%%%64 ' {0..64}
# shellcheck disable=SC2059  # format is variable.
printf -v _b64_tstr "$_b64_tstr" {0..64}
declare -Ai "B64R=($_b64_tstr)"
unset B64 _b64_tstr
declare -r B64R
b64ToHex52() {
    local _line _Tail _v _opt OPTIND _resArry
    local -i iFd _ar
    while getopts "av:" _opt; do case $_opt in
        a) _ar=1;; v) _v=${OPTARG};; *) return 1;; esac; done
    shift $((OPTIND-1))
    if [[ $_v ]];then local -n _res=${_v}; else local _res; fi
    if [[ $1 ]]; then    exec {iFd}<<<"$1"     # Open Input FD from string
    else                 exec {iFd}<&0   ; fi  # Open Input FD from STDIN
    mapfile -tu $iFd _lines
    read -ra _resArry <<<"${_lines[*]//?/& }"
    printf -v _tmpStr '"B64R[%s]<<18|B64R[%s]<<12|B64R[%s]<<6|B64R[%s]" ' \
           "${_resArry[@]}"
    local -ia "_tmpArry=($_tmpStr)"
    printf -v _tmpStr '%06x' "${_tmpArry[@]}"
    read -ra _res <<<"${_tmpStr//??/& }"
    exec {iFd}<&-
    _Tail=${_lines[-1]##*([^=])}
    _res=("${_res[@]::${#_res[@]}-${#_Tail}}")
    ((_ar==0)) && printf -v _res %s "${_res[@]}" && _res=("${_res[0]}")
    [[ -z $_v ]] && echo "${_res[@]}"
}

4. Execution time comparison

Well, now a little comparison test by doing repetitively same conversion to compute execution time.

I now have 4 functions:

  1. b64toHex My version using base64 and xxd
  2. b64ToHex My pure bash version (notice upper T)
  3. b64ToHex52 My pure bash using bash version 5.2+
  4. base64_to_hex from accepted answer.

Here's my little test function:

testB64decoders(){ 
    local TIMEFORMAT='r %3lR,  u %3lU,  s %3lS, p %P' bunch \
        inString="${2:-SGVsbG8gd29ybGQhIFRoaXMgaXMgYSB0ZXN0IHN0cmluZy4=}"
    printf -v bunch '%*s' ${1:-100} ''
    mapfile -t bunch <<<"${bunch// /$'\n'}"
    printf ' - %-29s: ' "3 fork (base64 | xxd)";
    time for i in "${bunch[@]}"; do b64toHex hx "$inString"; done
    printf ' - %-29s: ' "Pure bash";
    time for i in "${bunch[@]}"; do b64ToHex -v Hx "$inString"; done;
    printf ' - %-29s: ' "Pure bash V5.2+";
    time for i in "${bunch[@]}"; do b64ToHex52 -v Hx5 "$inString"; done;
    printf ' - %-29s: ' "5 fork =\$(echo| base64 | xxd)";
    time for i in "${bunch[@]}"; do hex=$(base64_to_hex "$inString"); done;
    [[ $hx == "$hex" ]] && [[ $Hx == "$hx" ]] && [[ $Hx5 == "$hx" ]] &&
        printf -v inString '%b' ${hx//??/\\x&} &&
        printf 'Hopefully result strings are same (%s).\n' "${inString@Q}"
}

Let's show with a small thousand of operation:

testB64decoders 1000

Could produce something like:

 - 3 fork (base64 | xxd)        : r 0m2.032s,  u 0m2.315s,  s 0m0.699s, p 148.32
 - Pure bash                    : r 0m0.965s,  u 0m0.735s,  s 0m0.213s, p 98.14
 - Pure bash V5.2+              : r 0m0.571s,  u 0m0.477s,  s 0m0.088s, p 98.91
 - 5 fork =$(echo| base64 | xxd): r 0m2.433s,  u 0m3.242s,  s 0m0.989s, p 173.92

Where r for real, u: user, s: system time and p: cpu percentage is: 100 * ( u + s ) / r

  • pure bash method is quicker,
  • pure bash method using bash 5.2+ is significantly quicker,
  • version using xxd and base64 with only two fork will even be a little quicker than
  • version using four forks (a subshell to run three more forks to xxd, base64 and tr). They are the slowest, and yes: two more forks do have system footprint.

Note: on a multicore system, user time is bigger than real time, thanks to parallelization

On my Raspberry-Pi II model B, I had to reduce my test down to 20 loops.

testB64decoders 20

Did produce on my RPi II:

 - 3 fork (base64 | xxd)      …
2 of 2
3

xxd -p may have \n chars in the output so you need to remove them:

base64_to_hex()
{
    echo "$1" | base64 --decode | xxd -p | tr -d '\n'
}

Use your base64 string as example:

$ hex=$( base64_to_hex OQbb8rXnj/DwvglW018uP/1tqldwiJMbjxBhX7ZqwTw= )
$ echo $hex
3906dbf2b5e78ff0f0be0956d35f2e3ffd6daa577088931b8f10615fb66ac13c
🌐
Reddit
reddit.com › r/bash › help need to decipher this command: xxd
r/bash on Reddit: Help need to decipher this command: xxd
March 25, 2022 -

First and foremost, I just want to say that I'm relatively new to Bash and I'm taking a pen testing course. This is the command that I need help to decipher because I don't understand how it works:

echo '4f537b32393736656137393964633562333261343431353535313735303937346230317d0a0a' | xxd -r -p

I think that this command pipes in hex code to xxd, which is a utility used to make a hexdump or do the reverse (as explainshell says). The -r option tells xxd to convert the hexdump into binary and the -p option tells it to output the binary string in plain hexdump style. However, the output is not in binary. It seems to be in (I don't know the technical term for it) regular language (OS) and contains a hex string ({2976ea799dc5b32a4415551750974b01}):

OS{2976ea799dc5b32a4415551750974b01}

Why is the output not in binary?

Top answer
1 of 4
5
Greetings, I have used xxd along with the same parameters to pipe binary characters to a binary file. The reason you are seeing ascii characters is because all the command with those parameters displays the result in ascii and all of your characters from the binary conversion result in regular ascii characters. I found this from a quick search to confirm: https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ If you try this one from terminal you will see it outputs special characters because it cannot display them from a terminal. echo 0ee221ef9e00dfa69efb3b1112bfbb2f | xxd -r -p The sample I listed is part of this script (I'm the author) and used with file encryption. Basically it converts hex to binary and appends the binary bytes to a binary file. Near the bottom of the document I list step by step example of encryption and how to use the commands. For this script xxd is critical because it's the only way to convert to and from hex from shell without installing additional tools. https://fastsitephp.com/en/documents/file-encryption-bash # Append IV to the end of the file. # Typically in secure applications and sites the IV is saved with the # encrypted data while only the key is required to be secret. echo 0ee221ef9e00dfa69efb3b1112bfbb2f | xxd -r -p >> crypto_test_10mb.enc # Now view the end of the file after adding IV tail -c 32 crypto_test_10mb.enc | hexdump -C -v
2 of 4
2
The output is in binary. The command outputs the binary values corresponding to the hexadecimal values 4f, 53, 7b, 32 etc. When sent to the terminal those binary values are interpreted as characters: hex 4f (aka decimal 79, binary 01001111, etc) is a capital O, 53 is a capital S, 7b is an open curly brace, 32 is the digit "2", etc. xxd is doing its job - you just for some reason have a hex string representing the text OS{2976ea799dc5b32a4415551750974b01}. I have no idea what that text represents.
🌐
Ubuntu
manpages.ubuntu.com › trusty › man(1)
Ubuntu Manpage: xxd - make a hexdump or do the reverse.
xxd creates a hex dump of a given file or standard input. It can also convert a hex dump back to its original binary form. Like uuencode(1) and uudecode(1) it allows the transmission of binary data in a `mail-safe' ASCII representation, but has the advantage of decoding to standard output.
🌐
Université catholique de Louvain
sites.uclouvain.be › SystInfo › manpages › man1 › xxd.1.html
Man page of XXD
xxd creates a hex dump of a given file or standard input. It can also convert a hex dump back to its original binary form. Like uuencode(1) and uudecode(1) it allows the transmission of binary data in a `mail-safe' ASCII representation, but has the advantage of decoding to standard output.