将二进制数据转换为 C 程序的十六进制字符串

发布于 2024-11-01 19:15:52 字数 187 浏览 1 评论 0原文

我有一个小的二进制图像,需要用 C 程序表示。表示形式如下:(

static const char[] = {0x1, 0x2, 0x3, 0x4...};

因此,字节将表示为一系列字符)

如何将二进制文件转换为漂亮的 0x..,0x.. 字符串?有一个程序可以做到这一点吗?

I have a small binary image, that needs to be represented in a C program. The representation will be like:

static const char[] = {0x1, 0x2, 0x3, 0x4...};

(so, the bytes will be represented as a series of chars)

How do I convert a binary file into a nice 0x..,0x.. string? Is there a program to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

从此见与不见 2024-11-08 19:15:52

使用 xxd 实用程序:

$ xxd -i binary.bin > binary.c

将创建二进制文件。 c 包含以下内容:

unsigned char binary_bin[] = {
  0x01, 0x02, 0x03, 0x04,   . . .
  . . .
};
unsigned int binary_bin_len = 123456;

Use the xxd utility:

$ xxd -i binary.bin > binary.c

Will create binary.c with the following content:

unsigned char binary_bin[] = {
  0x01, 0x02, 0x03, 0x04,   . . .
  . . .
};
unsigned int binary_bin_len = 123456;
苏佲洛 2024-11-08 19:15:52
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LENGTH 80

int main(void)
{
    FILE *fout = fopen("out.txt", "w");

    if(ferror(fout))
    {
        fprintf(stderr, "Error opening output file");
        return 1;
    }
    char init_line[]  = {"char hex_array[] = { "};
    const int offset_length = strlen(init_line);

    char offset_spc[offset_length];

    unsigned char buff[1024];
    char curr_out[64];

    int count, i;
    int line_length = 0;

    memset((void*)offset_spc, (char)32, sizeof(char) * offset_length - 1);
    offset_spc[offset_length - 1] = '\0';

    fprintf(fout, "%s", init_line);

    while(!feof(stdin))
    {
        count = fread(buff, sizeof(char), sizeof(buff) / sizeof(char), stdin);

        for(i = 0; i < count; i++)
        {
            line_length += sprintf(curr_out, "%#x, ", buff[i]);

            fprintf(fout, "%s", curr_out);
            if(line_length >= MAX_LENGTH - offset_length)
            {
                fprintf(fout, "\n%s", offset_spc);
                line_length = 0;
            }
        }
    }
    fseek(fout, -2, SEEK_CUR);
    fprintf(fout, " };");

    fclose(fout);

    return EXIT_SUCCESS;
}

在这里,更新,有效。通过管道输入文件,它会将其作为十六进制的无符号字符数组吐出到 out.txt。

另一个编辑:我想我不妨把它做得更好。将其打印到 out.txt,这是一个无符号字符数组,格式良好。如果您想向其中添加任何内容,从这里开始应该是微不足道的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LENGTH 80

int main(void)
{
    FILE *fout = fopen("out.txt", "w");

    if(ferror(fout))
    {
        fprintf(stderr, "Error opening output file");
        return 1;
    }
    char init_line[]  = {"char hex_array[] = { "};
    const int offset_length = strlen(init_line);

    char offset_spc[offset_length];

    unsigned char buff[1024];
    char curr_out[64];

    int count, i;
    int line_length = 0;

    memset((void*)offset_spc, (char)32, sizeof(char) * offset_length - 1);
    offset_spc[offset_length - 1] = '\0';

    fprintf(fout, "%s", init_line);

    while(!feof(stdin))
    {
        count = fread(buff, sizeof(char), sizeof(buff) / sizeof(char), stdin);

        for(i = 0; i < count; i++)
        {
            line_length += sprintf(curr_out, "%#x, ", buff[i]);

            fprintf(fout, "%s", curr_out);
            if(line_length >= MAX_LENGTH - offset_length)
            {
                fprintf(fout, "\n%s", offset_spc);
                line_length = 0;
            }
        }
    }
    fseek(fout, -2, SEEK_CUR);
    fprintf(fout, " };");

    fclose(fout);

    return EXIT_SUCCESS;
}

Here, updated, works. Pipe in the file, it spits it out as an unsigned char array in hex to out.txt.

Another edit: Figured I might as well make it nice. Prints it out to out.txt, an unsigned char array and nicely formatted. Should be trivial from here if you want to add anything to it

走走停停 2024-11-08 19:15:52

在Python 2.6中

from __future__ import with_statement
with open('myfile.bin') as f:
    s = f.read()
    for c in s:
        print hex(ord(c)) + ",",

In Python 2.6

from __future__ import with_statement
with open('myfile.bin') as f:
    s = f.read()
    for c in s:
        print hex(ord(c)) + ",",
×纯※雪 2024-11-08 19:15:52

如果 pBuff 是您的二进制数据,请尝试计算出缓冲区的长度,例如

lenBuffer= sizeof(..);
for (i = 0; i < lenBuffer; i++)
  printf("%x ", pBuff[i]);

If pBuff is your binary data, try to figure out the length of your buffer, e.g.

lenBuffer= sizeof(..);
for (i = 0; i < lenBuffer; i++)
  printf("%x ", pBuff[i]);
雄赳赳气昂昂 2024-11-08 19:15:52

您可以编写一个程序来非常轻松地完成此操作,但这里有一个 perl 脚本那可以为你做到。

You can write a program to do it pretty easily, but here is a perl script that can do it for you.

往日 2024-11-08 19:15:52
二智少女 2024-11-08 19:15:52

开源应用程序 Hexy 是专门为此设计的。
它在 Windows 和 Linux 上运行。

The open source application Hexy is designed specifically for this.
It runs on Windows and Linux.

自由如风 2024-11-08 19:15:52

效果很好!不过,我做了一个小更改,以允许在命令行上指定输入和输出文件:

int main(int argc, char **argv)
{
    FILE *fout = NULL;
    FILE *fin = NULL;
    const char *optstring = "i:o";
    char ch;
    int argind = 1;

    if(argc < 5)
    {
            fprintf(stderr,"Usage: bin2array -i <input_file> -o <output_file>\n");
            return 2;
    }

    while((ch = getopt(argc,argv,optstring)) != -1)
    {
            switch(ch)
            {
            case 'i':
                    argind++;
                    fprintf(stderr,"File: %s\n",argv[argind]);
                    fin = fopen(argv[argind],"rb");
                    argind++;
                    break;
            case 'o':
                    argind++;
                    fprintf(stderr,"File: %s\n",argv[argind]);
                    fout = fopen(argv[argind],"wt");
                    argind++;
                    break;
            }
    }

    ....
}

Works great! However I made a small change to allow for the input and output files to be specified on the command line:

int main(int argc, char **argv)
{
    FILE *fout = NULL;
    FILE *fin = NULL;
    const char *optstring = "i:o";
    char ch;
    int argind = 1;

    if(argc < 5)
    {
            fprintf(stderr,"Usage: bin2array -i <input_file> -o <output_file>\n");
            return 2;
    }

    while((ch = getopt(argc,argv,optstring)) != -1)
    {
            switch(ch)
            {
            case 'i':
                    argind++;
                    fprintf(stderr,"File: %s\n",argv[argind]);
                    fin = fopen(argv[argind],"rb");
                    argind++;
                    break;
            case 'o':
                    argind++;
                    fprintf(stderr,"File: %s\n",argv[argind]);
                    fout = fopen(argv[argind],"wt");
                    argind++;
                    break;
            }
    }

    ....
}
等风也等你 2024-11-08 19:15:52

此 Python 代码/脚本生成二进制 blob 的 C/C++ 字符串。八进制转义符使字符串比十六进制转义符短。

#!/usr/bin/env python3

"""
:c_str_literal():
produces `"<ascii with special C escapes and oct escapes else>"` from a python `bytes` object.

The whole file converts a binary file into a file
containing the string produced by c_str_literal().

#Test
python -c 'with open("/tmp/test_bin2c_py.dat","bw") as f: f.write(bytes(range(256)))'
python ./bin2c.py /tmp/test_bin2c_py.dat
cat << EOF > /tmp/test_bin2c_py.cpp
#include <cassert>
unsigned char data[] = 
#include "test_bin2c_py.dat.inc"
;
// sizeof(data) includes a terminating 0
int main() {assert(data[0]==0 && data[sizeof(data)-2]==255);}
EOF
g++ /tmp/test_bin2c_py.cpp -std=c++17 -o /tmp/test_bin2c_py && /tmp/test_bin2c_py
rm /tmp/test_bin2c_py.dat.inc
rm /tmp/test_bin2c_py.cpp
cat /tmp/test_bin2c_py.dat | python ./bin2c.py
rm /tmp/test_bin2c_py.dat
"""

import sys

c_str_literal = lambda d: '"{}"'.format(''.join(bytes_to_c_ascii_oct(d)))
def bytes_to_c_ascii_oct(d):
   """Convert binary data to C/C++ ASCII encoding.
   >>> d=bytes([0,ord('0'),3,ord('9'),ord(' '),ord('\t'),13])
   >>> c_str_literal(d)
   '"\\0000\\39 \\t\\r"'
   >>> d=bytes(range(256))
   >>> c_str_literal(d)[:9]
   '"\\0\\1\\2\\3'
   >>> c_str_literal(d)[-9:]
   '\\376\\377"'
   >>> d=bytes([92,56])
   >>> c_str_literal(d)
   '"\\\\8"'
   >>> d=b'\a\b\f\r\t\v\'\"\n'
   >>> c_str_literal(d)
   '"\\7\\b\\f\\r\\t\\v\'\\"\\n"'
   >>> d=bytes([63,63,ord('<')])
   >>> c_str_literal(d)
   '"\\?\\?<"'
   >>> from base64 import b64decode as b64d
   >>> d=b64d("2y1+2oAR6w8dzIYARovDfz/PD7JA8NW/fEteMTPNmpK7oswK8wWwR1ZMgH8//9Q74xRdcIWfPk8nr/9Pq9xQGDFv")
   >>> c_str_literal(d)[-8:]
   'P\\0301o"'

   """
   b2enc = ['\\0', '\\1', '\\2', '\\3', '\\4', '\\5', '\\6', '\\7', '\\b', '\\t', '\\n',
      '\\v', '\\f', '\\r', '\\16', '\\17', '\\20', '\\21', '\\22', '\\23', '\\24',
      '\\25', '\\26', '\\27', '\\30', '\\31', '\\32', '\\33', '\\34', '\\35', '\\36',
      '\\37', ' ', '!', '\\"', '#', '
, '%', '&', "'", '(', ')', '*', '+',
      ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':',
      ';', '<', '=', '>', '\\?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
      'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
      'Z', '[', '\\\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
      'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
      'y', 'z', '{', '|', '}', '~', '\\177', '\\200', '\\201', '\\202', '\\203', '\\204',
      '\\205', '\\206', '\\207', '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216',
      '\\217', '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227', '\\230',
      '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237', '\\240', '\\241', '\\242',
      '\\243', '\\244', '\\245', '\\246', '\\247', '\\250', '\\251', '\\252', '\\253', '\\254',
      '\\255', '\\256', '\\257', '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266',
      '\\267', '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277', '\\300',
      '\\301', '\\302', '\\303', '\\304', '\\305', '\\306', '\\307', '\\310', '\\311', '\\312',
      '\\313', '\\314', '\\315', '\\316', '\\317', '\\320', '\\321', '\\322', '\\323', '\\324',
      '\\325', '\\326', '\\327', '\\330', '\\331', '\\332', '\\333', '\\334', '\\335', '\\336',
      '\\337', '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347', '\\350',
      '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357', '\\360', '\\361', '\\362',
      '\\363', '\\364', '\\365', '\\366', '\\367', '\\370', '\\371', '\\372', '\\373', '\\374',
      '\\375', '\\376', '\\377']
   ord0,ord7,o16 = ord('0'),ord('7'),14
   lend = len(d)
   i,j = 0,1
   while j <= lend:
       di = d[i]
       bi = b2enc[di]
       if j == lend:
           yield bi
           break
       dj = d[j]
       if ((di<=7 or (di>=o16 and di<32))
           and dj>=ord0 and dj<=ord7):
           yield '\\'+"{:0>3o}".format(di)
       else:
           yield bi
       i,j = i+1,j+1

if __name__ == '__main__':
   a = sys.argv
   if len(a) > 2 or len(a)==2 and (a[1]=='--help' or a[1]=='-h'):
       print("{} [<filename>|--help|-h]".format(a[0]))
       print("stdin/stdout if no file name is given, else '.inc' is appended")
       exit(0)
   fi = len(a)==2 and open(a[1],'br') or sys.stdin.buffer
   fo = len(a)==2 and open(a[1]+'.inc','w') or sys.stdout
   d = fi.read()
   fo.write(c_str_literal(d))

This Python code/script produces a C/C++ string of a binary blob. Octal escapes makes the string shorter than hex escapes.

#!/usr/bin/env python3

"""
:c_str_literal():
produces `"<ascii with special C escapes and oct escapes else>"` from a python `bytes` object.

The whole file converts a binary file into a file
containing the string produced by c_str_literal().

#Test
python -c 'with open("/tmp/test_bin2c_py.dat","bw") as f: f.write(bytes(range(256)))'
python ./bin2c.py /tmp/test_bin2c_py.dat
cat << EOF > /tmp/test_bin2c_py.cpp
#include <cassert>
unsigned char data[] = 
#include "test_bin2c_py.dat.inc"
;
// sizeof(data) includes a terminating 0
int main() {assert(data[0]==0 && data[sizeof(data)-2]==255);}
EOF
g++ /tmp/test_bin2c_py.cpp -std=c++17 -o /tmp/test_bin2c_py && /tmp/test_bin2c_py
rm /tmp/test_bin2c_py.dat.inc
rm /tmp/test_bin2c_py.cpp
cat /tmp/test_bin2c_py.dat | python ./bin2c.py
rm /tmp/test_bin2c_py.dat
"""

import sys

c_str_literal = lambda d: '"{}"'.format(''.join(bytes_to_c_ascii_oct(d)))
def bytes_to_c_ascii_oct(d):
   """Convert binary data to C/C++ ASCII encoding.
   >>> d=bytes([0,ord('0'),3,ord('9'),ord(' '),ord('\t'),13])
   >>> c_str_literal(d)
   '"\\0000\\39 \\t\\r"'
   >>> d=bytes(range(256))
   >>> c_str_literal(d)[:9]
   '"\\0\\1\\2\\3'
   >>> c_str_literal(d)[-9:]
   '\\376\\377"'
   >>> d=bytes([92,56])
   >>> c_str_literal(d)
   '"\\\\8"'
   >>> d=b'\a\b\f\r\t\v\'\"\n'
   >>> c_str_literal(d)
   '"\\7\\b\\f\\r\\t\\v\'\\"\\n"'
   >>> d=bytes([63,63,ord('<')])
   >>> c_str_literal(d)
   '"\\?\\?<"'
   >>> from base64 import b64decode as b64d
   >>> d=b64d("2y1+2oAR6w8dzIYARovDfz/PD7JA8NW/fEteMTPNmpK7oswK8wWwR1ZMgH8//9Q74xRdcIWfPk8nr/9Pq9xQGDFv")
   >>> c_str_literal(d)[-8:]
   'P\\0301o"'

   """
   b2enc = ['\\0', '\\1', '\\2', '\\3', '\\4', '\\5', '\\6', '\\7', '\\b', '\\t', '\\n',
      '\\v', '\\f', '\\r', '\\16', '\\17', '\\20', '\\21', '\\22', '\\23', '\\24',
      '\\25', '\\26', '\\27', '\\30', '\\31', '\\32', '\\33', '\\34', '\\35', '\\36',
      '\\37', ' ', '!', '\\"', '#', '
, '%', '&', "'", '(', ')', '*', '+',
      ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':',
      ';', '<', '=', '>', '\\?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
      'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
      'Z', '[', '\\\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
      'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
      'y', 'z', '{', '|', '}', '~', '\\177', '\\200', '\\201', '\\202', '\\203', '\\204',
      '\\205', '\\206', '\\207', '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216',
      '\\217', '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227', '\\230',
      '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237', '\\240', '\\241', '\\242',
      '\\243', '\\244', '\\245', '\\246', '\\247', '\\250', '\\251', '\\252', '\\253', '\\254',
      '\\255', '\\256', '\\257', '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266',
      '\\267', '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277', '\\300',
      '\\301', '\\302', '\\303', '\\304', '\\305', '\\306', '\\307', '\\310', '\\311', '\\312',
      '\\313', '\\314', '\\315', '\\316', '\\317', '\\320', '\\321', '\\322', '\\323', '\\324',
      '\\325', '\\326', '\\327', '\\330', '\\331', '\\332', '\\333', '\\334', '\\335', '\\336',
      '\\337', '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347', '\\350',
      '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357', '\\360', '\\361', '\\362',
      '\\363', '\\364', '\\365', '\\366', '\\367', '\\370', '\\371', '\\372', '\\373', '\\374',
      '\\375', '\\376', '\\377']
   ord0,ord7,o16 = ord('0'),ord('7'),14
   lend = len(d)
   i,j = 0,1
   while j <= lend:
       di = d[i]
       bi = b2enc[di]
       if j == lend:
           yield bi
           break
       dj = d[j]
       if ((di<=7 or (di>=o16 and di<32))
           and dj>=ord0 and dj<=ord7):
           yield '\\'+"{:0>3o}".format(di)
       else:
           yield bi
       i,j = i+1,j+1

if __name__ == '__main__':
   a = sys.argv
   if len(a) > 2 or len(a)==2 and (a[1]=='--help' or a[1]=='-h'):
       print("{} [<filename>|--help|-h]".format(a[0]))
       print("stdin/stdout if no file name is given, else '.inc' is appended")
       exit(0)
   fi = len(a)==2 and open(a[1],'br') or sys.stdin.buffer
   fo = len(a)==2 and open(a[1]+'.inc','w') or sys.stdout
   d = fi.read()
   fo.write(c_str_literal(d))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文