In Python I want to tranform the integer 3892 into a hexcode with the given format and the result \x00\x00\x0F\x34. How can this be achieved?
3 Answers
You are converting to a binary representation of the number, not so much a hex representation (although Python will display the bytes as hex). Use the struct module for such conversions.
Demonstration:
>>> struct.pack('>I', 3892)
'\x00\x00\x0f4'
>>> struct.pack('>I', 4314)
'\x00\x00\x10\xda'
Note that the ASCII code for '4' is 0x34, python only displays bytes with a \x escape if it is a non-printable character. Because 0x34 is printable, python outputs that as 4 instead.
'>' in the formatting code above means 'big endian' and 'I' is an unsigned int conversion (4 bytes).
4 Comments
martineau
Isn't 3892 decimal 0xf34 hexadecimal?
Martijn Pieters
@martineau: I address that in my answer; python displays '4' because that is the ASCII character at code position 0x34. Thus, the last character in the byte sequence is
\x34 but because it is printable it is not displayed as a hex escape.martineau
Ahhh, I get what you meant by the statement in your answer now, thanks. It's unclear if the OP wants this or what @cdarke's answer produces, but suspect it's probably the former, so will have to add my own +1.
Martijn Pieters
Updated with a second, independent example that does produce 4 unprintable bytes.
import re
print re.sub(r'([0-9A-F]{2})',r'\\x\1','%08X' % 3892)
gives:
\x00\x00\x0F\x34
3 Comments
fernandes
wow! thats it - really cool. Thanks a lot. @cdarke for the sake of my mediocre regex-skills: could you give me a short explenation of your regex?
Martijn Pieters
This produces a 16-character string with literal backslash, literal
x and literal digits. '%08X' produces the hexadecimal digits, and the regular expression inserts a literal \x every two digits. My solution produces 4 bytes, which contain your number as an unsigned C long value. You need to figure out what format you need to write to your file; if it is a binary format my bet is on my answer. :-)cdarke
Sorry for the delay, I have been travelling. The RE is as follows (in addition to @Martijn Pieters correct explaination):
([0-9A-F]{2}) looks for exactly 2 hexadecimal digits. The parentheses () capture what we matched, and are represented in the replacement string as \1 (called a back-reference). \\x prefixes the captured two characters with \x. Would be nice if you accepted my solution if you are happy with it, but I agree with others that your question is a little ambiguous.If you have numpy installed:
>>> import numpy as np
>>> np.int32(3892).tostring()
'4\x0f\x00\x00'
1 Comment
fernandes
Thanks for the fast answers! But I need as actual result the \x00\x00\x0F\x34 as I have to import it back into a file. Is it possible to do this?
0x0f34on a big-endian machine, or do you mean literally the character string"\\x00\\x00\\x0F\\x34"?