2014-01-16 3 views
2

Я использую Python 2.7.X.
У меня есть текстовый файл со следующим содержанием:Python: преобразовать строку в ее двоичное представление

\xe87\x00\x10LOL 

Заметьте, что это сам текст, а не его двоичное представление (то есть первый символ «\\», не 0xE8) Когда Я прочитал его (как двоичный), я получаю:

a = "\\\\xe87\\\\x00\\\\x10LOL" 

потому что это текстовый файл.

Я хочу, чтобы преобразовать его в двоичной форме, то есть я хочу, чтобы получить файл, который начинается с символов
0xE8, 0x37, 0x00, 0x10, 0x4c, 0x4F, 0x4c.
(Обратите внимание, что 0x4c == 'L', 0x4f == 'O').

Как это сделать?
Пробовал всевозможные решения, такие как hexlify \ unhexlify, int (c, 16), но похоже, что я чего-то не хватает.
Также обратите внимание, что длина файла изменяется, поэтому struct.pack менее предпочтителен.

+0

Вы дон '' действительно хотите прочитать символ '" 7 "' как '0x07', не так ли? –

+0

Какую версию Python вы используете? – falsetru

+0

@TimPietzcker, ты прав. Я установил его на 0x37 (== '7') – Sammy

ответ

2

Использование string-escape or unicode-escape encoding:

>>> content = r'\xe87\x00\x10LOL' 
>>> print content 
\xe87\x00\x10LOL 
>>> content 
'\\xe87\\x00\\x10LOL' 
>>> content.decode('string-escape') 
'\xe87\x00\x10LOL' 
>>> map(hex, map(ord, content.decode('string-escape'))) 
['0xe8', '0x37', '0x0', '0x10', '0x4c', '0x4f', '0x4c'] 

>>> bytes(map(ord, content.decode('string-escape'))) 
'[232, 55, 0, 16, 76, 79, 76]' 

>>> bytearray(map(ord, content.decode('string-escape'))) 
bytearray(b'\xe87\x00\x10LOL') 
+0

Это работает почти из коробки. Пришлось удалить внешнюю карту и заменить ее bytearray: 'bytearray (map (ord, content.decode ('string-escape')))'. Отличный ответ, я не знал этого расшифровки. – Sammy

+0

@Sammy, Спасибо за отзыв. Я обновил ответ в соответствии с вашими комментариями. – falsetru

2

Вот один из способов сделать это:

In [26]: a = r"\xe87\x00\x10LOL" 

In [27]: b = ast.literal_eval("'" + a + "'") 

In [28]: open("test.dat", "w").write(b) 

In [29]: 
[1]+ Stopped     ipython 
$ xxd test.dat 
0000000: e837 0010 4c4f 4c      .7..LOL 

(Есть, вероятно, более совершенные инструменты, чем literal_eval, но это первое, что пришло в голову в этот ранний час утром).

+0

Это работает из коробки, но я считаю это менее изящным :) – Sammy

0

"".join([chr(int(i,16)) for i in data.split("\\x") if i])

+0

Это не должно работать, поскольку не все символы в исходной строке начинаются с «\\ x» (обратите внимание на «7» в моем примере). – Sammy

+0

@ Сэмми, ты прав. Я пропустил эту часть. благодаря – Elisha