Discussion:
Hex to ASCII conversion?
Bob Proulx
2014-12-25 20:04:30 UTC
Permalink
I have a string of hex encoded us-ascii characters. The hex sequence
48 61 70 70 79 is obviously "Happy". Is there an easy way to convert
them to ascii using printf? It seems like there should be.

$ printf "%c\n" 0x48 0x61 0x70 0x70 0x79
0
0
0
0
0

Nope. It doesn't operate like C does.

$ printf "%c\n" h e l l o
h
e
l
l
o

Although of course I can use printf to convert from hex to decimal it
looks like I can't use it for converting from hex to ascii.

Of course the perl printf works like the C printf.

$ perl -le 'printf("%c\n",0x48);'
H

So this works.

$ for c in 48 61 70 70 79; do perl -le 'printf("%c\n",0x'$c');'; done; echo
H
a
p
p
y

Is there any way to use the shell printf like the C printf and do this
conversion in the coreutils printf? Or perhaps another way?

Bob
Bernhard Voelker
2014-12-25 22:09:48 UTC
Permalink
Post by Bob Proulx
I have a string of hex encoded us-ascii characters. The hex sequence
48 61 70 70 79 is obviously "Happy". Is there an easy way to convert
them to ascii using printf? It seems like there should be.
$ printf "%c\n" 0x48 0x61 0x70 0x70 0x79
0
0
0
0
0
[...]
Is there any way to use the shell printf like the C printf and do this
conversion in the coreutils printf? Or perhaps another way?
I only know of the double-folded printf way via octal:

$ env printf $(env printf '\\%03o' 0x48 0x61 0x70 0x70 0x79)
Happy

(The additional 'env' is to force the use of coreutils printf rather
than that of the shell.)

This is e.g. used in tests/dd/ascii.sh to get all bytes from 0..255
as ASCII characters.

Have a nice day,
Berny
Bob Proulx
2014-12-27 00:13:15 UTC
Permalink
Post by Bernhard Voelker
$ env printf $(env printf '\\%03o' 0x48 0x61 0x70 0x70 0x79)
Happy
Oh, that is clever! And I got a hint from another friend that I
shared that question with too. I learned something about printf that
I hadn't known. I hadn't grok'd that it would interpret all character
escape sequences. Of course it is obvious that it does but I hadn't
internalized it. You and my friend George both gave me the same hint
back. As they say, great minds think alike!

But that means it can be done simply by having printf read the escape
sequence.

$ printf "\x48\x61\x70\x70\x79\n"
Happy

Aha! And for me there was the moment of insight that I was looking to
acquire. That is the syntax!

It is quite easy by an endless number of different ways to reformat
the hex codes so that printf can manage it now. The original was a
reverse DNS lookup return so had dots separating them.

$ echo 48.61.70.70.79.20 | while read -d. c; do printf "\x$c";done;echo
Happy

And if anyone is interested in the reason I wanted this there was a
very nice hack that floated around the Internet this Christmas. It
was actually broken yesterday which is why I didn't mention it in my
previous message. It would have been cruel to mention it when it
wasn't working. But I see they have it back working again today!
Yay! It is fun. It is best to run with a wide terminal 100+ or
wider. If you follow the output closely and with the hex hints above
it will lead you to the authors of the hack.

traceroute -m255 xmas.futile.net

Enjoy!
Bob

Loading...