Как получить бинарный код файла

Обновлено: 05.07.2024

Эксперимент с бинарным файлом на языке Python

Чтобы понять, как работать с файлами в бинарном формате проведем несколько экспериментов. Рассмотрим в начале файл, состоящий из текстовых строк и посмотрим результат чтения его в бинарном формате. Вот этот файл ( file1 )

1234
qwer
абсд

Программа p400.py считывает файл в строку h и далее мы печатаем эту строку обычной функцией print() . В результате на консоль выводится следующее:

Представленные выше данные есть ни что иное, как массив байтов (bytes), к элементам которого можно обращаться по индексу . Ниже, в программе p400b.py мы используем его для преобразования списка чисел. В следующей статье мы вернемся к нему подробнее.

Файл, как числовой список в языке Python

Теперь посмотрим, как можно получить содержимое файла в виду массива чисел ( p400a.py ).

Результат выполнения программы p400a.py:

49 50 51 52 10 113 119 101 114 10 208 176 208 177 209 129 208 180 10 10

Т.е. мы получили просто последовательность байтов некоторого файла. Обращаю внимание на код 10, который попадается в последовательности. Это как раз символ перехода на новую строку.

Обратно к текстовому файлу на языке Python

Ну и последнее, что хотелось бы сегодня рассказать о бинарных файлах (а это не последний урок), как полученную последовательность чисел опять превратить в файл. Смотрим программу p400b.py .

За исходную последовательность чисел мы взяли как раз последовательность полученную в программе p400b.py . В результате работы мы получим снова файл, содержащий строки

1234
qwer
абсд

т.е. копию первоначального файла. Обращаю внимание на массив bytes , который использовался нами для записи в файл.

На сегодня о бинарных файлах все. Но продолжение следует. Следующая статья здесь .

Пока! Программируем на Python и подписываемся на мой канал Old Programmer .

Всем доброго времени суток. Хочу написать скрипт на Perl (сразу говорю просто так, ради академического интереса) который будет читать файл, различными образами его криптовать и выводить потом отдельный индивидуальный ключ для его расшифровки. Но обрабатывать я хочу любой файл, а не тока текстовый, так что использовать что то вроде ord (x) и chr (x) не хочу, такое уже есть. Насколько мне ведомо, любой файл - это набор из битов. Вот их я и хочу получить. Чтоб можно было потом превратить в нечитаемый любой файл, хоть TXT, хоть JPG, хоть EXE. Вопрос: как прочитать файл именно в том виде каким его воспринимает процессор? Через binmode? И как потом перекодировать назад? Или считать ту область памяти.ю где он находится и в том состоянии, в котором он там находится. У меня что-то не получается. Подскажите, что можно использовать или может как то вызвать встроенные функции линукса (Хотя приоритет - именно возможностями Perl-а)



Лучше python использовать там есть режим чтения (и записи) байтов из файла.

XoFfiCEr ★★★★ ( 10.11.12 20:40:34 )
Последнее исправление: XoFfiCEr 10.11.12 20:42:01 (всего исправлений: 1)


Вопрос: как прочитать файл именно в том виде каким его воспринимает процессор? Через binmode?

Имеете в виду, в том виде, в котором он записан на диске? Используйте ":raw" PerlIO layer.

Подскажите, что можно использовать или может как то вызвать встроенные функции линукса

Начните с реализации алгоритма XOR (A xor key = crypted; crypted xor key = A).

А для реального шифрования используйте gpg (например, gpg -c).


Алгоритма XOR хватит если его по умному применить. Вот так правильно

XoFfiCEr ★★★★ ( 10.11.12 20:42:43 )
Последнее исправление: XoFfiCEr 10.11.12 20:43:59 (всего исправлений: 2)


Вариант, но его я тока начинаю изуать а с Perl уже более-менее знаком. Вот и хотел из него что-нибудь выдепить этакое. Но все равно спасибо.


Дело в том что я вчера бездельничая на работе, начал писать скрипт для шифрования. Получалось шифрование в 6 проходов, это вполне достаточно imho.


получил свои долгожданные нолиики-единички, но при обратной процедуре

обломался. Файл в первоначальное состояние возвращаться не хочет.


Я в perl увы ничего не понимаю.


Не используйте pack() на больших значениях. Для сдвига битов напишите код на C, поскольку работа с отдельными битами на Perl (особенно с использованием pack() и unpack()) довольно медленна.

У меня есть файл размером чуть больше 500 МБ, который вызывает некоторые проблемы.

Я считаю, что проблема в соглашении конца строки (EOL). Я хотел бы посмотреть на файл в его неинтерпретированной необработанной форме (1), чтобы подтвердить соглашение EOL о файле.

Как я могу просмотреть «двоичный» файл, используя что-то встроенное в Windows 7? Я бы предпочел не загружать что-либо дополнительное.

(1) Мой коллега и я открыли файл в текстовых редакторах, и они показывают строки, как и следовало ожидать. Но оба текстовых редактора будут открывать файлы с различными соглашениями EOL и интерпретировать их автоматически. (TextEdit и Emacs 24.2. Для Emacs я создал второй файл с использованием только первых 4K-байтов head -c4096 в окне Linux и открыл его из окна Windows.

Я попытался использовать hexl-режим в Emacs, но когда я перешел в hexl-режим и вернулся в текстовый режим, содержимое буфера изменилось, добавив видимый ^ M в конец каждой строки, так что я не доверяя этому на данный момент.

Я полагаю, что проблема может быть в конце строки символов. Редакторы, которые мы с коллегой пытались (1), просто автоматически определили в конце строки и показали нам строки. И на основании других доказательств я считаю, что конвенция EOL касается только возврата каретки. (2) вернуть только.

Чтобы узнать, что на самом деле находится в файле, я хотел бы взглянуть на двоичное содержимое файла или, по крайней мере, на пару тысяч байт файла, предпочтительно в шестнадцатеричном формате, хотя я мог бы работать с десятичным или восьмеричным. На один ноль было бы довольно грубо смотреть.

ОБНОВИТЬ

За исключением предложенного DEBUG , все ответы ниже в той или иной степени работают. Я проголосовал за каждого из них как полезного. Мой вопрос был плохо сформирован. При тестировании каждого предложенного решения я обнаружил, что я действительно хотел, чтобы рядом просматривался шестнадцатеричный и текстовый контент, и что я хотел, чтобы это было что-то, где когда я наводил курсор на что-либо, либо на байтовое значение, либо на текстовый символ, то, что соответствовало на другая сторона будет выделена.

В данной теме показано как можно сохранять данные в бинарных файлах без использования стандартных средств pickle или struct языка Python.

Содержание

  • 1. Понятие о бинарных файлах. Представление информации в бинарных файлах
  • 2. Запись/чтение списка, который содержит вещественные числа. Пример
  • 3. Запись/чтение кортежа, содержащего строки символов. Пример
  • 4. Запись/чтение множества, содержащего вещественные числа. Пример
  • 5. Запись/чтение двумерной матрицы строк заданного размера. Пример
  • 6. Запись/чтение словаря. Пример
  • 7. Копирование одного бинарного файла в другой
  • 8. Объединение двух бинарных файлов

Поиск на других ресурсах:

1. Понятие о бинарных файлах. Представление информации в бинарных файлах

В языке Python существуют средства для работы с бинарными или двоичными файлами. Бинарные файлы используют строки типа bytes . Это значит при чтении бинарных данных из файла возвращается объект типа bytes .

Пример, демонстрирующий особенности представления информации в бинарных файлах.

Результат работы программы

На основании примера выше можно сделать следующие выводы:

2. Запись/чтение списка, который содержит вещественные числа. Пример

Результат работы программы

3. Запись/чтение кортежа, содержащего строки символов. Пример

Результат работы программы

4. Запись/чтение множества, содержащего вещественные числа. Пример

Множество, которое содержит только однотипные объекты можно записать в файл. В данном примере записывается множество вещественных чисел.

Результат работы программы

Вид файла myfile6.bin

5. Запись/чтение двумерной матрицы строк заданного размера. Пример

В примере матрица представлена в виде списка.

Результат работы программы

Вид файла myfile7.txt

6. Запись/чтение словаря. Пример

Пусть задан некоторый словарь, который нужно записать в бинарный файл.

Результат работы программы

Вид файла myfile8.txt

7. Копирование одного бинарного файла в другой
8. Объединение двух бинарных файлов. Пример

В примере реализована операция объединения двух файлов в результирующий третий файл. Сначала данные с файлов-источников считываются в списки. Затем происходит конкатенация этих списков и запись результирующего списка в файл результата.

Т екстовые файлы хранят данные в виде текста (sic!). Это значит, что если, например, мы записываем целое число 12345678 в файл, то записывается 8 символов, а это 8 байт данных, несмотря на то, что число помещается в целый тип. Кроме того, вывод и ввод данных является форматированным, то есть каждый раз, когда мы считываем число из файла или записываем в файл происходит трансформация числа в строку или обратно. Это затратные операции, которых можно избежать.

Текстовые файлы позволяют хранить информацию в виде, понятном для человека. Можно, однако, хранить данные непосредственно в бинарном виде. Для этих целей используются бинарные файлы.

Выполните программу и посмотрите содержимое файла output.bin. Число, которое ввёл пользователь записывается в файл непосредственно в бинарном виде. Можете открыть файл в любом редакторе, поддерживающем представление в шестнадцатеричном виде (Total Commander, Far) и убедиться в этом.

Запись в файл осуществляется с помощью функции

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

Запись в бинарный файл объекта похожа на его отображение: берутся данные из оперативной памяти и пишутся как есть. Для считывания используется функция fread

Функция возвращает число удачно прочитанных элементов, которые помещаются по адресу ptr. Всего считывается count элементов по size байт. Давайте теперь считаем наше число обратно в переменную.

fseek

Одной из важных функций для работы с бинарными файлами является функция fseek

Эта функция устанавливает указатель позиции, ассоциированный с потоком, на новое положение. Индикатор позиции указывает, на каком месте в файле мы остановились. Когда мы открываем файл, позиция равна 0. Каждый раз, записывая байт данных, указатель позиции сдвигается на единицу вперёд.
fseek принимает в качестве аргументов указатель на поток и сдвиг в offset байт относительно origin. origin может принимать три значения

  • SEEK_SET - начало файла
  • SEEK_CUR - текущее положение файла
  • SEEK_END - конец файла. К сожалению, стандартом не определено, что такое конец файла, поэтому полагаться на эту функцию нельзя.

В случае удачной работы функция возвращает 0.

Дополним наш старый пример: запишем число, затем сдвинемся указатель на начало файла и прочитаем его.

Вместо этого можно также использовать функцию rewind, которая перемещает индикатор позиции в начало.

В си определён специальный тип fpos_t, который используется для хранения позиции индикатора позиции в файле.
Функция

используется для того, чтобы назначить переменной pos текущее положение. Функция

используется для перевода указателя в позицию, которая хранится в переменной pos. Обе функции в случае удачного завершения возвращают ноль.

возвращает текущее положение индикатора относительно начала файла. Для бинарных файлов - это число байт, для текстовых не определено (если текстовый файл состоит из однобайтовых символов, то также число байт).

Рассмотрим пример: пользователь вводит числа. Первые 4 байта файла: целое, которое обозначает, сколько чисел было введено. После того, как пользователь прекращает вводить числа, мы перемещаемся в начало файла и записываем туда число введённых элементов.

Вторая программа сначала считывает количество записанных чисел, а потом считывает и выводит числа по порядку.

Примеры

1. Имеется бинарный файл размером 10*sizeof(int) байт. Пользователь вводит номер ячейки, после чего в неё записывает число. После каждой операции выводятся все числа. Сначала пытаемся открыть файл в режиме чтения и записи. Если это не удаётся, то пробуем создать файл, если удаётся создать файл, то повторяем попытку открыть файл для чтения и записи.

2. Пишем слова в бинарный файл. Формат такой - сначало число букв, потом само слово без нулевого символа. Ели длина слова равна нулю, то больше слов нет. Сначала запрашиваем слова у пользователя, потом считываем обратно.

3. Задача - считать данные из текстового файла и записать их в бинарный. Для решения зачи создадим функцию обёртку. Она будет принимать имя файла, режим доступа, функцию, которую необходимо выполнить, если файл был удачно открыт и аргументы этой функции. Так как аргументов может быть много и они могут быть разного типа, то их можно передавать в качестве указателя на структуру. После выполнения функции файл закрывается. Таким образом, нет необходимости думать об освобождении ресурсов.

4. Функция saveInt32Array позволяет сохранить массив типа int32_t в файл. Обратная ей loadInt32Array считывает массив обратно. Функция loadInt32Array сначала инициализирует переданный ей массив, поэтому мы должны передавать указатель на указатель; кроме того, она записывает считанный размер массива в переданный параметр size, из-за чего он передаётся как указатель.

5. Создание таблицы поиска. Для ускорения работы программы вместо вычисления функции можно произвести сначала вычисление значений функции на интервале с определённой точностью, после чего брать значения уже из таблицы. Программа сначала производит табулирование функции с заданными параметрами и сохраняет его в файл, затем подгружает предвычисленный массив, который уже используется для определения значений. В этой программе все функции возвращают переменную типа Result, которая хранит номер ошибки. Если функция отработала без проблем, то она возвращает Ok (0).

6. У нас имеются две структуры. Первая PersonKey хранит логин, пароль, id пользователя и поле offset. Вторая структура PersonInfo хранит имя и фамилию пользователя и его возраст. Первые структуры записываются в бинарный файл keys.bin, вторые структуры в бинарный файл values.bin. Поле offset определяет положение соответствующей информации о пользователе во втором файле. Таким образом, получив PersonKey из первого файла, по полю offset можно извлечь из второго файла связанную с данным ключом информацию.

Зачем так делать? Это выгодно в том случае, если структура PersonInfo имеет большой размер. Извлекать массив маленьких структур из файла не накладно, а когда нам понадобится большая структура, её можно извлечь по уже известному адресу в файле.

email

Всё ещё не понятно? – пиши вопросы на ящик

Читайте также: