Конвертирайте двоични файлове в ascii в Python

Имам куп двоични файлове, които съдържат данни в следния формат:

i\xffhh\xffhh\xffhh\xffih\xffhh\xffhh\xffhh\xffhh\xffhi\xffii\xffjj\xffjj\xffjj\xffjk\xffkk\xffkk\xffkl\xffll\xffmm\xffmn\xffnn\xffon\xffno\xffop\xffop\xffpp\xffqq\xffrq\xffrs\xffst\xfftt\xfftt\xffuv\xffvu\xffuv\xffvv\xffvw\xffwx\xffwx\xffxy\xffyy\xffyz\xffz{\xffz{\xff||\xff}|\xff~}\xff}}\xff~~\xff~~\xff~\x7f\xff\x7f\x7f\xff\x7f\x7f\xff\x7f\x7f\xff\x80\x80\xff\x80\x81\xff\x81\x80\xff\x81\x81\xff\x81\x82\xff\x82\x82\xff\x82\x82\xff\x82\x83\xff\x83\x83\xff\x83\x83\xff\x83\x84\xff\x83\x84\xff\x84\x85\xff\x85\x85\xff\x86\x85\xff\x86\x87\xff\x87\x87\xff\x87\x87\xff\x88\x87\xff\x88\x89\xff\x88\x89\xff\x89\x8a\xff\x89\x8a\xff\x8a\x8b\xff\x8b\x8b\xff\x8b\x8c\xff\x8d\x8d\xff\x8d\x8d\xff\x8e\x8e\xff\x8e\x8f\xff\x8f\x8f

Предполага се, че това са показанията на сензора за налягане, когато човек ходи, така че предполагам, че са числа, но искам да ги конвертирам в ASCII, за да имам някаква представа какво представляват. Как да ги конвертирам? В какъв формат са в момента?

РЕДАКТИРАНЕ: Връзка към предоставения тук файл (Връзка)


person GobiasKoffi    schedule 18.11.2010    source източник
comment
Това е интересно, защото изглежда, че те започват да имат смисъл още при първия \x7f. Предполагам, че гледате това в редактор, който превежда някои двоични знаци в знаци извън шестнадесетичния диапазон (~ тилда например не е шестнадесетичен знак). Можете ли да ни покажете дъмпа от действителен шестнадесетичен редактор, да поставите връзка към файла или да разберете файловия формат, но търсите в документацията за устройството, което използвате?   -  person marr75    schedule 18.11.2010
comment
Може да бъде 3 байта на проба, като средният байт винаги е 255 по някаква причина. От какво устройство идват данните?   -  person Gareth Rees    schedule 18.11.2010
comment
Страхотен! Стигнах до този въпрос, защото искам да хакна файла за калибриране (.cal3) на сензор за налягане FootWork. Малък свят!   -  person heltonbiker    schedule 09.08.2011


Отговори (3)


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

Разбира се, когато знаете формата, е лесно да прочетете файла в двоичен режим и след това да получите всички значими данни от него

FILE = open(filename,"rb")
FILE.read(numBytes)
person pyfunc    schedule 18.11.2010
comment
...и за декодиране на данните след четене можете да използвате struct module: docs.python.org /library/struct.html - person che; 18.11.2010
comment
Това ли е отговор? Получавате ли 45 Zorkmids за това? - person John Machin; 16.12.2010
comment
Vincent написа: получих грешка numBytes не е дефиниран. Отговор: NumBytes е цяло число, представляващо брой байтове за четене. Ако файлът е малък, можете да оставите това празно, за да прочетете целия файл. - person cadvena; 27.06.2016

Аз съм абсолютно шокиран и зашеметен и не малко изумен от вафлите като „имате букви като hh, които не трябва да са част от шестнадесетично число“ и „изглежда започват да имат смисъл още при първия \x7f“ . Никой ли не е виждал изход от repr()?

Следното показва как може да е свършило така, игнорирайки \xff, което изглежда просто шум:

>>> pressure = [120,121,122,123,124,125,126,127,128,129,130,131]
>>> import struct
>>> some_bytes = struct.pack("12B", *pressure)
>>> print repr(some_bytes)
'xyz{|}~\x7f\x80\x81\x82\x83'
>>>

Така че нека опитаме да работим обратно от файла:

>>> guff = open('your_file.bin', 'rb').read()
>>> cleaned = guff.replace("\xff", "")
>>> cleaned
'ihhhhhhihhhhhhhhhhiiijjjjjjjkkkkkklllmmmnnnonnoopopppqqrqrsstttttuvvuuvvvvwwxwx
xyyyyzz{z{||}|~}}}~~~~~\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x80\x80\x80\x81\x81\x80\x81\
x81\x81\x82\x82\x82\x82\x82\x82\x83\x83\x83\x83\x83\x83\x84\x83\x84\x84\x85\x85\
x85\x86\x85\x86\x87\x87\x87\x87\x87\x88\x87\x88\x89\x88\x89\x89\x8a\x89\x8a\x8a\
x8b\x8b\x8b\x8b\x8c\x8d\x8d\x8d\x8d\x8e\x8e\x8e\x8f\x8f\x8f'
# Note that lines wrap at column 80 in a Windows "Command Prompt" window ...
>>> pressure = [ord(c) for c in cleaned]
>>> pressure
[105, 104, 104, 104, 104, 104, 104, 105, 104, 104, 104, 104, 104, 104, 104, 104,
 104, 104, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107,
 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 110, 110, 111, 111,
 112, 111, 112, 112, 112, 113, 113, 114, 113, 114, 115, 115, 116, 116, 116, 116,
 116, 117, 118, 118, 117, 117, 118, 118, 118, 118, 119, 119, 120, 119, 120, 120,
 121, 121, 121, 121, 122, 122, 123, 122, 123, 124, 124, 125, 124, 126, 125, 125,
 125, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 128, 128, 128,
 129, 129, 128, 129, 129, 129, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131,
 131, 131, 132, 131, 132, 132, 133, 133, 133, 134, 133, 134, 135, 135, 135, 135,
 135, 136, 135, 136, 137, 136, 137, 137, 138, 137, 138, 138, 139, 139, 139, 139,
 140, 141, 141, 141, 141, 142, 142, 142, 143, 143, 143]
>>>

Все пак ще трябва да прочетете документите за оборудването, за да разберете какъв е коефициентът на мащаба, по който да умножите тези стойности 0-254.

Ще забележите, че получените числа се променят с +1, 0 или -1 всеки път. Това се вписва удобно в хипотезата, че това е само 1 байт на четене, а не два или повече байта на четене.

Друга мисъл: може би \xff е начален или краен страж и има две стойности (старт, стоп) или (сензор-A, сензор-B), които се отчитат всеки цикъл.

person John Machin    schedule 16.12.2010

Първата част изглежда много странно. Обикновено число като \x8e е просто код за това, че е байт в шестнадесетичен, освен че в първата част имате букви като hh, които не трябва да са част от шестнадесетично число.

Но за втората част можете да направите нещо като:

hex_list = r"\x7f\xff\x7f\x7f\xff\x7f\x7f\xff\x7f\x7f\xff\x80\x80\xff\x80\x81\xff\x81\x80\xff\x81\x81\xff\x81\x82\xff\x82\x82\xff\x82\x82\xff\x82\x83\xff\x83\x83\xff\x83\x83\xff\x83\x84\xff\x83\x84\xff\x84\x85\xff\x85\x85\xff\x86\x85\xff\x86\x87\xff\x87\x87\xff\x87\x87\xff\x88\x87\xff\x88\x89\xff\x88\x89\xff\x89\x8a\xff\x89\x8a\xff\x8a\x8b\xff\x8b\x8b\xff\x8b\x8c\xff\x8d\x8d\xff\x8d\x8d\xff\x8e\x8e\xff\x8e\x8f\xff\x8f\x8f"
int_list =  [int(hex,16) for hex in hex_list.replace('\\', ';0').split(';') if hex != '']

Имайте предвид, че винаги получавате число между 127 и 143, с изключение на 255 (\xff).

person dr jimbob    schedule 18.11.2010