Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I use Python 2.7.X.
I have a text file with the following content:

\xe87\x00\x10LOL  

Note that this is the text itself, and not its binary representation (meaning the first char is '\\', not 0xe8) When I read it (as binary), I get:

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

because it is a text file.

I want to convert it to a binary form, meaning I want to get a file which begins with the characters
0xe8, 0x37, 0x00, 0x10, 0x4c, 0x4f, 0x4c.
(Note that 0x4c == 'L', 0x4f == 'O').

How do I do that?
Tried all sorts of solutions like hexlify\unhexlify, int(c, 16), but it seems like I'm missing something.
Also note that the length of the file varies, so struct.pack is less preferred.

share|improve this question
    
You don't really want to read the character "7" as 0x07, do you? –  Tim Pietzcker Jan 16 at 7:37
    
Which Python version do you use? –  falsetru Jan 16 at 7:37
    
@TimPietzcker, you're right. I fixed it to 0x37 (== '7') –  Sammy Jan 16 at 7:40
    
@falsetru, Python 2.7 –  Sammy Jan 16 at 7:41
    
Possible duplicate of stackoverflow.com/questions/209513/… –  Elisha Jan 16 at 7:44

3 Answers 3

up vote 2 down vote accepted

Using 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')
share|improve this answer
    
This works almost out of the box. Had to remove the outer map, and replace it with a bytearray: bytearray(map(ord, content.decode('string-escape'))). Great answer, I didn't know that decoding. –  Sammy Jan 16 at 9:41
    
@Sammy, Thank you for the feedback. I updated the answer according to your comment. –  falsetru Jan 16 at 9:44

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

share|improve this answer
    
That shouldn't work, since not all chars in the original string begin with "\\x" (note the '7' in my example). –  Sammy Jan 16 at 9:43
    
@Sammy oh, you are right. I missed that part. Thanks –  Elisha Jan 16 at 18:01

Here is one way to do it:

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

(There are probably better tools than literal_eval, but that's the first that came to mind at this early hour in the morning.)

share|improve this answer
    
That works out of the box but I consider it less elegant :) –  Sammy Jan 16 at 9:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.