Reputation: 568
I currently work on some binary data. In order to check and debug the data previously generated by my application I use hexdump, facing the obstacle of hexdump not appearing to be able to extract a 64-bit integer field. Given the following minimal example:
#include <iostream>
#include <fstream>
#include <cstdint>
int main(int argc, char** argv){
std::ofstream os("tmp.bin", std::ios::out | std::ios::binary);
uint64_t x = 7;
os.write((char*)&x,sizeof(uint64_t));
os.close();
return 0;
}
I perform a simple hexdump on my system:
hexdump tmp.bin
> 0000000: 0007 0000 0000 0000
> 0000008:
Now trying to extract the unsigned int of 64 bit width yields:
hexdump -e '/8 "%u"' tmp.bin
> hexdump: bad byte count for conversion character u
According to the well written hexdump-manual by David Mair it should be possible to do it, but I have no success.
What am I missing ?
Upvotes: 6
Views: 14135
Reputation: 470
I don't understand why this doesn't work out-of-the-box, but I had the same problem printing 64-bit integers and ended up compiling a better version from util-linux
found here: https://github.com/karelzak/util-linux. At first I tried installing that package in Ubuntu, but it didn't update hexdump
, so I decided to try doing it "manually."
It's a bit of work, but not too bad. Just use git
to grab the source, run the autogen.sh
script, and then ./configure
followed by make hexdump
to compile just that program. Compiling only took 4 seconds on my laptop.
Upvotes: 0
Reputation: 291
One can use sed also. The following matches 8 byte hex integers and swaps them. Again this only works for unsigned integers.
hexdump ... | sed 's/0x\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)/0x\2\1/'
AFAICT one should be able to write much more clearly
hexdump ... | sed 's/0x\([0-9a-f]{8,8}\)\([0-9a-f]{8,8}\)/0x\2\1/'
typically with some command line option such as -E to enable extended regular expressions, but at least on Mac OS X 10.10 this doesn't work.
Upvotes: 1
Reputation: 568
Our final workaround reads as follows:
x=`hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME} | awk 'BEGIN{printf "0x"}{print $2$1}'`
echo $(($x))
Explaination for each part:
Extract the eight bytes of the 64-bit integer value from file {FILENAME} as two four byte chunks printed as hexadecimal encoded values.
hexdump -n 8 -e '2/4 "%08X " "\n"' {FILENAME}
Reverses the byte order of the two chunks and prints it as a single eight byte chunk representing the binary value. Prepend 0x for the following processing.
awk 'BEGIN{printf "0x"}{print $2$1}
Save the hexadecimal representation into x for bash to evaluate.
x=`....`
Let the bourne shell interpret and output the hexadecimal encoded value of the 64-bit integer variable (here the previously prepended 0x is needed).
echo $(($x))
Upvotes: 3