-1

I have a small binary file. I want to import that binary file into a C program as a character array like so:

char some_binary_data[] = "\000-type or \xhh-type escape sequences and such here";

Is there a standard shell command that can render binary data with C-style escaping? Bonus points if I can choose between octal-style escapes and hex-style escapes.

For example, if my file contains the bytes

0000000 117000 060777 000123
0000006

, I'd like to render it as "\000\236\377a\123".

Brandon Yarbrough
  • 37,021
  • 23
  • 116
  • 145
  • 3
    Are you opposed to writing a small program that does that? It's going to be a fairly trivial program. – R Sahu Feb 19 '16 at 18:32
  • 2
    http://stackoverflow.com/q/8707183/3776858 ? – Cyrus Feb 19 '16 at 18:35
  • It's a dupe, but yeah, the `xxd` tool is what you're looking for. See [this superuser answer](http://superuser.com/a/638850) for where you can get one for Windows. It should be installed on any modern Unix that has vim installed, e.g. on RHEL it's in `vim-common` package. – Kuba hasn't forgotten Monica Feb 19 '16 at 19:08

2 Answers2

2

Here's something I put together that should work:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>

int main(int argc, char *argv[])
{
    int infile = open(argv[1], O_RDONLY);
    if (infile == -1) {
        perror("open failed");
        exit(1);
    }

    FILE *outfile = fopen(argv[2],"w");
    if (!outfile) {
        perror("fopen failed");
        exit(1);
    }
    fprintf(outfile, "char %s[] = ", argv[3]);

    int buflen;
    int totallen, i, linelen;
    char buf[1000];
    totallen = 0;
    linelen = atoi(argv[4]);
    while ((buflen=read(infile, buf, sizeof(buf))) > 0) {
        for (i=0;i<buflen;i++) {
            if (totallen % linelen == 0) {
                fprintf(outfile, "\"");
            }
            if (buf[i] == '\"' || buf[i] == '\\') {
                fprintf(outfile,"\\%c",buf[i]);
            } else if (isalnum(buf[i]) || ispunct(buf[i]) || buf[i] == ' ') {
                fprintf(outfile,"%c",buf[i]);
            } else {
                fprintf(outfile,"\\x%02X",buf[i]);
            }
            if (totallen % linelen == linelen - 1) {
                fprintf(outfile, "\"\n    ");
            }
            totallen++;
        }
    }
    if (totallen % linelen != 0) {
        fprintf(outfile, "\"");
    }
    fprintf(outfile, ";\n");

    close(infile);
    fclose(outfile);
    return 0;
}

Sample input:

This is a "test".  This is only a \test.

Called as:

/tmp/convert /tmp/test1 /tmp/test1.c test1 10

Sample output

char test1[] = "This is a "
    "\"test\".  Th"
    "is is only"
    "a \\test.\x0A"
    ;
dbush
  • 205,898
  • 23
  • 218
  • 273
1

There isn't one exactly like that to my knowledge, but "od" is close if you're in the *nix world, or mac. Don't know about windoz.

Here's a shell script

#!/bin/bash

if [ ! -f "$1" ]; then
        echo file "$1" does not exist
        exit
        fi

if [ -z $2 ]; then
        echo output file not specfied
        exit
        fi

echo "char data[]=" > $2
od -t x1 $1 |awk '/[^ ]*  *[^ ]/ {printf("      \"");for(i=2;i<=NF;++i)printf("\\x%s", $i); print "\""}' >> $2
echo "  ;" >> $2
Bing Bang
  • 524
  • 7
  • 16