Форум программистов, компьютерный форум, киберфорум
Python
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.79/56: Рейтинг темы: голосов - 56, средняя оценка - 4.79
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
1

Считывание бинарного файла в виде нулей и единиц

16.04.2013, 10:30. Просмотров 10123. Ответов 12
Метки нет (Все метки)


Всем привет.
Необходимо реализовать помехоустойчивое кодирование для файла(код Хэмминга, если быть точным). Для этого мне необходимо каждый байт входного файла рассматривать в виде последовательности бит и иметь доступ к каждому биту.
Сам алгоритм кодирования для текстовых файлов реализовал без проблем(каждый считываемый символ приводил к нужному виду с помощью
Python
1
"%08i" % int(bin(ord('CHAR'))[2:])
), но с бинарными файлами не получается.

Суть проблемы:
Python
1
2
3
4
5
6
7
Python 3.2.3 (default, Oct 19 2012, 19:53:57) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open("file", "rb").read()
>>> f
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x18\x08\x06\x00\x00\x00\xe0w=\xf8\x00\x00\x04\xc3IDATx\xda\xa5\x95{P\x94U\x18\xc6#\xd0LED \x8c\x16A\x04\xba\x89d\x80"\x06\xec\xda:\xa9\x85\xe4TvE\xb2\x9c)\xcaf\x84
....
Если всякие \x89 и проч спокойно можно привести к виду 01010101, то как быть например с "PNG", "w=", "\r", "{P", "LED" и прочими словами, встречающимися в выводе?

Буду рад любой помощи.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.04.2013, 10:30
Ответы с готовыми решениями:

Вывод любого файла в виде последовательности нулей и единиц в memo
Задача поставлена следующим образом: открыть файл любого расширения и вывести его представление в...

Записать последовательность нулей и единиц в виде байтов
Здравствуйте, очень нужна помощь. Есть список нулей и единиц, и нужно их преобразовать в виде...

Получить двоичное представление числа р в виде последовательности нулей и единиц
Дано натуральное число р. Получить двоичное представление числа р в виде последовательности а0,...

Считывание с бинарного файла
Реализовать программу, которая считывает из исходного текстового файла записи определенной...

12
Эксперт С++
2189 / 1608 / 253
Регистрация: 29.05.2011
Сообщений: 3,305
16.04.2013, 12:02 2
А в чём проблема? Любой из указанных символов можно записать с помощью его кода.
Например '\r' это то же самое, что '\x0d'
'PNG' можно записать как '\x50\x4e\x47'
Не важно как представлен символ, функция ord() всё равно вернёт его числовой код.
0
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
16.04.2013, 12:09  [ТС] 3
Тогда такое уточнение:
Чтобы получить код каждого символа, мне нужно "\x25" передать одной функции, а "PNG" - другой, как это сделать с наименьшими потерями? Нужно же распарсить всю эту строку и то, что попадает под шаблон "\x**" - в одну сторону, что нет - в другую?
0
Эксперт С++
2189 / 1608 / 253
Регистрация: 29.05.2011
Сообщений: 3,305
16.04.2013, 12:30 4
Нет. Все четыре указанных символа хранятся в памяти в виде числовых кодов. Это отображение на экране у них разное.
Python
1
2
for s in "\x25PNG":
    print bin(ord(s))
Результат:
0b100101
0b1010000
0b1001110
0b1000111
1
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
16.04.2013, 12:37  [ТС] 5
Спасибо большое, буду пробовать
0
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
23.04.2013, 01:24  [ТС] 6
Столкнулся с новой проблемой:
формирую нужную мне для записи строку, записываю в бинарном режиме в файл, вижу, что записывается 1276 байт(столько, сколько и должно), но размер файла на выходе = 1902 байта, соответственно, он не открывается так, как должен.

Python
1
2
3
4
5
6
def write_bin(path, STRING):
    DECODED_STRING = ""
    with open(path, "wb") as OUT_FILE:
        for i in range(0, len(STRING)):
            DECODED_STRING = DECODED_STRING + chr(int(STRING[i], 2))
        OUT_FILE.write(bytes(DECODED_STRING, "UTF-8"))
STRING = ['00101100', '10010111', ...

Добавлено через 21 час 44 минуты
Ребят, неужели никто ничем не может помочь?
0
Эксперт С++
2189 / 1608 / 253
Регистрация: 29.05.2011
Сообщений: 3,305
23.04.2013, 01:41 7
Так вроде ничего удивительного:
Код
>>> bytes("abc", "UTF-8")
b'abc'
>>> bytes("абв", "UTF-8")
b'\xd0\xb0\xd0\xb1\xd0\xb2'
Или что-то не понятно? Кодировка UTF-8 подразумевает, что для кодирования различных символов может использоваться разное количество байт. От одного до четырёх.
0
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
23.04.2013, 03:02  [ТС] 8
Это понятно.
Собственно, глобальный вопрос в том, как считать файл(не текстовый), а потом, грубо говоря, записать его в первозданном виде, чтобы, если это png - он открывался как png, если mp3 - как mp3 и т.д.
Считывание работает идеально, все преобразования, нужные мне, так же работают, как в одну, так и в другую сторону. Но вот с тем, чтобы записать файл в том же исходном виде назад - проблема.
Пробовал тот метод, который привел выше - он работает не так, как надо, откуда-то берутся лигние байты. Кто-нибудь может подсказать работающий метод? Или объяснить, что не так в этом?
0
217 / 202 / 63
Регистрация: 26.05.2011
Сообщений: 363
23.04.2013, 04:45 9
Цитата Сообщение от vebeer Посмотреть сообщение
Столкнулся с новой проблемой:
формирую нужную мне для записи строку, записываю в бинарном режиме в файл, вижу, что записывается 1276 байт(столько, сколько и должно), но размер файла на выходе = 1902 байта, соответственно, он не открывается так, как должен.

Python
1
2
3
4
5
6
def write_bin(path, STRING):
    DECODED_STRING = ""
    with open(path, "wb") as OUT_FILE:
        for i in range(0, len(STRING)):
            DECODED_STRING = DECODED_STRING + chr(int(STRING[i], 2))
        OUT_FILE.write(bytes(DECODED_STRING, "UTF-8"))
STRING = ['00101100', '10010111', ...

Добавлено через 21 час 44 минуты
Ребят, неужели никто ничем не может помочь?
Python
1
2
3
4
5
6
7
8
9
from array import array
from functools import partial
 
STRING = ['00101100', '10010111', ...
 
basetwo = partial(int, base=2)
data = array("B", map(basetwo, STRING))
with open(path, "wb") as OUT_FILE:
    data.tofile(OUT_FILE)
Добавлено через 13 минут
Python
1
2
3
# байты файла в двоичном виде можно так получить
with open(source, "rb") as fin:
    BINDATA = list(map("{:08b}".format, map(ord, f)))
1
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
23.04.2013, 05:41 10
Цитата Сообщение от vebeer Посмотреть сообщение
Или объяснить, что не так в этом?
при обработке бинарных файлов вообще нет понятия кодировки, следовательно, наличие у тебя там utf-8 уже говорит, что ты что-то не то делаешь

Цитата Сообщение от pyuser Посмотреть сообщение
Python
1
# байты файла в двоичном виде можно так получить
у него третий питон, итератор изменился
Python
1
2
3
4
5
>>> f = open('/etc/passwd', 'rb')
>>> next(f)
b'root:x:0:0:root:/root:/bin/bash\n'
>>> f.close()
>>>
vebeer, для работы с файлом тебе нужны только .read() и .write()
0
217 / 202 / 63
Регистрация: 26.05.2011
Сообщений: 363
23.04.2013, 10:34 11
Цитата Сообщение от accept Посмотреть сообщение
третий питон, итератор изменился
Тогда букв немного больше
Python
1
2
3
4
with open(source, "rb") as fin:
    tmp = array("B")
    tmp.fromfile(fin)
    BINDATA = list(map("{:08b}".format, tmp))
0
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
23.04.2013, 14:36 12
Цитата Сообщение от pyuser Посмотреть сообщение
Тогда букв немного больше
а array для чего?
Python
1
2
3
4
5
6
7
8
>>> f = open('/etc/passwd', 'rb')
>>> s = next(f)
>>> s
b'root:x:0:0:root:/root:/bin/bash\n'
>>> s[0]
114
>>> f.close()
>>>
0
2 / 2 / 2
Регистрация: 16.04.2013
Сообщений: 15
24.04.2013, 02:25  [ТС] 13
Цитата Сообщение от pyuser Посмотреть сообщение
Python
1
2
3
4
5
6
7
8
9
from array import array
from functools import partial
 
STRING = ['00101100', '10010111', ...
 
basetwo = partial(int, base=2)
data = array("B", map(basetwo, STRING))
with open(path, "wb") as OUT_FILE:
    data.tofile(OUT_FILE)
Огромное спасибо! Это именно то, что нужно, работает на "ура"
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.04.2013, 02:25

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

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

Считывание бинарного файла
Здравствуйте! Изначально нужно было прочитать почисленно текстовый файл и забить его в массив. Но...

Считывание из бинарного файла
СЧИТАТЬ ИЗ БИНАРНОГО ФАЙЛА ВСЕ ВЕЩЕСТВЕННЫЕ ЧИСЛА В МАССИВ И ВЫВЕСТИ ЕГО НА ЭКРАН. #include...

Из текстового файла загружается одномерный массив, состоящий из нулей и единиц
3. Из текстового файла загружается одномерный массив, состоящий из нулей и единиц. Количество тех и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.