Подтвердить что ты не робот

Script/инструмент для преобразования файла в массив исходного кода C/С++

Мне нужен инструмент script/, который читает двоичный файл и выводит массив исходного кода C/С++ (который представляет содержимое файла). Есть ли?


(Этот вопрос был удален ранее. Я вернул этот вопрос, потому что он ценен. Я искал именно это в Google и ничего не нашел. Конечно, это просто, но я бы сэкономил некоторые минут, если бы я нашел такой простой script, поэтому он ценен.

У этих вопросов также было много голосов без объяснения причин. Пожалуйста, прокомментируйте, прежде чем вы проголосуете, почему вы считаете, что это не имеет значения или имеет плохую ценность.

Этот вопрос также вызвал много путаницы в отношении того, о чем я прошу. Если что-то неясно, спросите пожалуйста. Я не знаю, как сделать это более ясным. См. Ответы для примеров.

Также (после постановки вопроса здесь) у меня уже есть несколько ответов. Я просто хочу поместить/связать их здесь (снова), потому что я думаю, что это может быть полезно для кого-то другого, ищущего это.)

4b9b3361

Ответ 1

В Debian и других дистрибутивах Linux по умолчанию (вместе с vim) установлен инструмент xxd, который, учитывая параметр -i, может делать то, что вы хотите:

[email protected]:~/Desktop$ echo Hello World\! > temp
[email protected]:~/Desktop$ xxd -i temp 
unsigned char temp[] = {
  0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21,
  0x0a
};
unsigned int temp_len = 13;

Ответ 2

Один простой инструмент можно найти здесь:

#include <stdio.h>
#include <assert.h>

int main(int argc, char** argv) {
    assert(argc == 2);
    char* fn = argv[1];
    FILE* f = fopen(fn, "rb");
    printf("char a[] = {\n");
    unsigned long n = 0;
    while(!feof(f)) {
        unsigned char c;
        if(fread(&c, 1, 1, f) == 0) break;
        printf("0x%.2X,", (int)c);
        ++n;
        if(n % 10 == 0) printf("\n");
    }
    fclose(f);
    printf("};\n");
}

Ответ 3

Принятый ответ с использованием инструмента xxd хорош, если вы работаете в * nix-подобной системе. Вот "одна строка" для любой системы, в которой есть исполняемый файл python:

python -c "import sys;a=sys.argv;open(a[2],'wb').write(('const unsigned char '+a[3]+'[] = {'+','.join([hex(b) for b in open(a[1],'rb').read()])+'};').encode('utf-8'))" <binary file> <header file> <array name>

<двоичный файл> - это имя файла, который вы хотите превратить в заголовок C, <заголовочный файл> - это имя файла заголовка, а <имя массива> - это имя, которое должен иметь массив.

Вышеприведенная однострочная команда Python выполняет примерно то же самое, что и следующая (гораздо более читаемая) программа Python:

import sys

with open(sys.argv[2],'wb') as result_file:
  result_file.write(b'const char %s[] = {' % sys.argv[3].encode('utf-8'))
  for b in open(sys.argv[1], 'rb').read():
    result_file.write(b'0x%02X,' % b)
  result_file.write(b'};')

Ответ 4

Этот инструмент компилируется в командной строке разработчика в C. Он выдает вывод на терминал, отображающий содержимое в файле "array_name.c", который создается. Обратите внимание, что некоторые терминалы могут отображать символ "\ b".

    #include <stdio.h>
    #include <assert.h>

    int main(int argc, char** argv) {
    assert(argc == 2);
    char* fn = argv[1];

    // Open file passed by reference
    FILE* f = fopen(fn, "rb");
    // Opens a new file in the programs location
    FILE* fw = fopen("array_name.c","w");

    // Next two lines write the strings to the console and .c file
    printf("char array_name[] = {\n");
    fprintf(fw,"char hex_array[] = {\n");

    // Declare long integer for number of columns in the array being made
    unsigned long n = 0;

    // Loop until end of file
    while((!feof(f))){
        // Declare character that stores the bytes from hex file
        unsigned char c;

        // Ignore failed elements read
        if(fread(&c, 1, 1, f) == 0) break;
        // Prints to console and file, "0x%.2X" ensures format for all
        // read bytes is like "0x00"
        printf("0x%.2X,", (int)c);
        fprintf(fw,"0x%.2X,", (int)c);

        // Increment counter, if 20 columns have been made, begin new line
        ++n;
        if(n % 20 == 0){
            printf("\n");
            fprintf(fw,"\n");
        }
    }

    // fseek places cursor to overwrite extra "," made from previous loop
    // this is for the new .c file. Since "\b" is technically a character
    // to remove the extra "," requires overwriting it.
    fseek(fw, -1, SEEK_CUR);

    // "\b" moves cursor back one in the terminal
    printf("\b};\n");
    fprintf(fw,"};\n");
    fclose(f);
    fclose(fw);
}

Ответ 5

Это двоичный файл для исходного кода Python генератора массива C, идентичный программе в ответе Альберта.

import sys
from functools import partial

if len(sys.argv) < 2:
  sys.exit('Usage: %s file' % sys.argv[0])
print("char a[] = {")
n = 0
with open(sys.argv[1], "rb") as in_file:
  for c in iter(partial(in_file.read, 1), b''):
    print("0x%02X," % ord(c), end='')
    n += 1
    if n % 16 == 0:
      print("")
print("};")

Ответ 6

Вопрос старый, но позвольте мне предложить простой инструмент, который можно использовать в качестве альтернативы...

Вы можете использовать графический инструмент под названием Fluid. Он на самом деле используется для разработки интерфейса для инструментария FLTK, но также может генерировать массив без знака для C++ из двоичного файла. Загрузите его с Muquit.

Fluid screenshot

Ответ 7

Я проверил все доступные параметры и решил создать собственную небольшую программу для преобразования:

https://github.com/TheLivingOne/bin2array/blob/master/bin2array.c

Он работает намного быстрее, чем bin2c и даже xxd, что важно для больших файлов, особенно если вы хотите встроить преобразование в вашу систему сборки. Например. для файла 50 Мб на моем компьютере:

bin2c.py> 20 секунд

Простые скрипты на Python - около 10 секунд

xxd - около 3 секунд

bin2array - около 0,4 с

Кроме того, он производит намного более компактный вывод и добавляет выравнивание в массив, на случай, если вы хотите поместить туда 32- или 64-битные значения.