Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Hex ASCII to raw binary on Unix-like

39 views
Skip to first unread message

Frederick Gotham

unread,
Sep 4, 2020, 1:38:34 PM9/4/20
to

On operating systems similar to Unix (e.g. Linux, MacOS, Android), there are a handful of ways that people convert an ASCII hexadecimal to raw binary at the command line. Typically one of the following is used:

xxd
hexdump
od
bc

As I work on embedded Linux a lot, where I don't have 'bash' and where there's a very limited number of utilities available, I'm trying to find the most basic way of achieving my objective -- that will work on pretty much every Unix-like system.

Lots of embedded Linux systems don't have hexdump, xxd, od, bc.

The most simple I've been able to make it is the following 3 ubiquitous programs:

echo
sed
xargs

Like this:

some_other_program | sed 's/../\\x&/g' | xargs echo -e

Can anyone think of an even more simple way?

Juha Nieminen

unread,
Sep 4, 2020, 3:20:20 PM9/4/20
to
Frederick Gotham <cauldwel...@gmail.com> wrote:
> Can anyone think of an even more simple way?

Since you are asking a C++ group, you could write it in C++ (or C),
but I don't know if it would be the simplest way. (Well, after it
has been implemented an compiled it will become really simple.)

But it would certainly be extremely efficient.

Of course implementing it depends on your requirements. What is
the exact input syntax? Is whitespace allowed (and to be ignored)?
What should happen if the input contains non-hexadecimal characters?
Should the program support input files and/or output files as
command-line parameters?

Richard

unread,
Sep 4, 2020, 3:38:27 PM9/4/20
to
[Please do not mail me a copy of your followup]

Frederick Gotham <cauldwel...@gmail.com> spake the secret code
<9a016cd0-7657-45f6...@googlegroups.com> thusly:

>Can anyone think of an even more simple way?

Why not write your own?

#include <cstdio>

int main(int argc, char *argv[])
{
while (!std::feof(stdin))
{
int val{};
if (std::scanf("%2x", &val) == 1)
{
std::printf("%c", static_cast<char>(val));
}
}
return 0;
}

> echo 22 | ./a.out
"
> (echo 22; echo 22) | ./a.out
""

scanf will skip interposing whitespace when parsing integers. You can
add additional whitespace handling if that is what you need.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Mr Flibble

unread,
Sep 4, 2020, 4:12:21 PM9/4/20
to
You are mistaken, macOS is not similar to UNIX, macOS *is* UNIX.

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."

Keith Thompson

unread,
Sep 4, 2020, 4:54:28 PM9/4/20
to
legaliz...@mail.xmission.com (Richard) writes:
> Frederick Gotham <cauldwel...@gmail.com> spake the secret code
> <9a016cd0-7657-45f6...@googlegroups.com> thusly:
>>Can anyone think of an even more simple way?
>
> Why not write your own?
>
> #include <cstdio>
>
> int main(int argc, char *argv[])
> {
> while (!std::feof(stdin))
> {
> int val{};
> if (std::scanf("%2x", &val) == 1)
> {
> std::printf("%c", static_cast<char>(val));
> }
> }
> return 0;
> }

I advise against using feof() to determine whether there's any remaining
input. The above will be an infinite loop if there's an input error.
Use the value returned by the input function. (In this case, scanf()
returns EOF on end-of-file or an input error.)

[...]

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

Sam

unread,
Sep 4, 2020, 9:00:46 PM9/4/20
to
Frederick Gotham writes:

> On operating systems similar to Unix (e.g. Linux, MacOS, Android), there are
> a handful of ways that people convert an ASCII hexadecimal to raw binary at
> the command line. Typically one of the following is used:
>
> xxd
> hexdump
> od
> bc
>
> As I work on embedded Linux a lot, where I don't have 'bash' and where
> there's a very limited number of utilities available, I'm trying to find the
> most basic way of achieving my objective -- that will work on pretty much
> every Unix-like system.
>
> Lots of embedded Linux systems don't have hexdump, xxd, od, bc.

od and hexdump are the most basic way to accomplish it. Trying to roll your
own only ends up reinventing the same wheels. They are tiny.

$ size /usr/bin/hexdump
text data bss dec hex filename
46758 2432 240 49430 c116 /usr/bin/hexdump

Your "hello world" will not be far off the mark from this one.

So, if you need to convert something with the smallest possible footprint,
you already have it: hexdump. The most you can gain from writing your own
code is saving yourself writing the code in hexdump that produces the
handful of other formats, other than hex.

Vir Campestris

unread,
Sep 6, 2020, 4:55:20 PM9/6/20
to
On 04/09/2020 18:38, Frederick Gotham wrote:
>
You have sed (109000 bytes on my system) but not xxd (18552 bytes)?

You picked the wrong tools.

Andy
0 new messages