7

I was wondering if anybody knew of a command line utility that would allow me to directly write hex values to a file. such that when a hexdump of the file is done the values that I enter would be spit out. It is vital that I write directly to hex as many of the value that I need to write do not have any unicode or ascii equivalent characters associated with them. Looking for something like:

writehex f6050000 ac7e0500 02000800 01000000 newfile
hexdump newfile 
hexdump 1.02
ts.event.1
00000000: f6050000 ac7e0500 02000800 01000000 .....~..........
16 bytes read

4 Answers 4

10

This Bash function should work for you:

writehex  ()
{
    local i
    while [ "$1" ]; do
        for ((i=0; i<${#1}; i+=2))
        do
            printf "\x${1:i:2}";
        done;
        shift;
    done
}

Alternative implementation:

writehex  ()
{
    local arg, i
    for arg; do
        for ((i=0; i<${#arg}; i+=2))
        do
            printf "\x${arg:i:2}"
        done
    done
}

To test it:

$ writehex abc00001ff | hexdump -C
00000000  ab c0 00 01 ff                                    |.....|
00000005

$ writehex f6050000 ac7e0500 02000800 01000000 | hexdump -C
00000000  f6 05 00 00 ac 7e 05 00  02 00 08 00 01 00 00 00  |.....~..........|
00000010

Another option would be to use xxd.

$ echo hello | xxd
0000000: 6865 6c6c 6f0a
$ echo hello | xxd | xxd -r
hello

Edit:

Additionally, you can use the -p option to accept somewhat freeform input data:

$ echo 'f6050000 ac7e0500 02000800 01000000' | xxd -r -p | hexdump -C
00000000  f6 05 00 00 ac 7e 05 00  02 00 08 00 01 00 00 00  |.....~..........|
00000010

Edit 2:

Modified function above to handle multiple input arguments (strings of hex digits separated by spaces).

2
  • Issue with xxd is that he needs to write characters that don't have ASCII equivs. He can't echo them if he can't type them ;) The bash function looks good though
    – brent
    Oct 22, 2010 at 19:07
  • 1
    @brent: In the first of my two xxd examples, the output format is shown. The second example shows feeding that output into xxd -r. It would be easy enough to create that feed from the data the OP shows. echo '0000000: 4e6f 7720 6973 2074 6865 2074 696d 6520' | xxd -r Oct 22, 2010 at 19:14
4

With perl:

perl -ne '@a=split;for(@a){print chr(hex($_))}' inputfile > outputfile

Where the content of inputfile is formatted:

42 43 44

outputfile would then contain BCD. You can prep your input file in vi like so:

:%s/ //g
:%s/\(.\{2\}\)/\1 /g

That will remove all spaces, then insert a space between every character.

The example you gave using that perl line:

$ cat inputfile
f6 05 00 00 ac 7e 05 00 02 00 08 00 01 00 00 00
$ hexdump outputfile
0000000 f6 05 00 00 ac 7e 05 00 02 00 08 00 01 00 00 00
0000010
1
  • Thanks the perl command worked like a charm with Cygwin.
    – Smeterlink
    Jan 7, 2020 at 21:09
2

What about a hex editor, like hexedit ou hexer? You can directly edit the file and type values in hexadecimal with them.

1
  • Sorry, although that would work, I'm looking for a scriptable solution
    – jcb344
    Oct 22, 2010 at 18:44
1

Just had the same challenge and found this solution. I tried to go with the solution from Dennis Williamson but it was very slow when implemented in a mass operation (had to convert ~60k sqlite blobs into files). I came up with a reimplementation of writehex which I wanted to share here:

writehex ()
{
  HEX=$(echo $1 | sed -re 's:([0-9A-F]{2}):\\x\1:g')
  echo -e $HEX
}

When it comes to performance the pro of it is that it just uses a single call to sed and a lightweight regex. Your mileage may vary but I found it to be much faster.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .