13
>>> struct.pack('2I',12, 30)
b'\x0c\x00\x00\x00\x1e\x00\x00\x00'    
>>> struct.pack('2I',12, 31)
b'\x0c\x00\x00\x00\x1f\x00\x00\x00'
>>> struct.pack('2I',12, 32)
b'\x0c\x00\x00\x00 \x00\x00\x00'
                  ^in question
>>> struct.pack('2I',12, 33)
b'\x0c\x00\x00\x00!\x00\x00\x00'
                  ^in question

I'd like all values to display as hex

4
  • 1
    ' ' === '\x20', '!' === '\x21' Commented Dec 27, 2013 at 19:25
  • 1
    I know but how can I get it display as a hex number, so everything is uniform? Commented Dec 27, 2013 at 19:26
  • Do you mean, in the interactive console? I'd say it makes everything to not use hex codes, as strings are not supposed to hold unprintable characters, so you'd need to format them as hex codes manually; but then they'll show with double backslashes in the console. Commented Dec 27, 2013 at 19:27
  • Im writing code to create a special packet, and for debug purposes I want to see where things are getting packed so I'm printing it out. I could use print from my code Commented Dec 27, 2013 at 19:29

5 Answers 5

18

See bytes.hex():

>>> import struct
>>> struct.pack('2I', 12, 30).hex()  # available since Python 3.5
'0c0000001e000000'
>>> struct.pack('2I', 12, 30).hex(' ')  # separator available since Python 3.8
'0c 00 00 00 1e 00 00 00'
>>> struct.pack('2I', 12, 30).hex(' ', 4)  # bytes_per_sep also since Python 3.8
'0c000000 1e000000'

Older Python use binascii.hexlify:

>>> import binascii
>>> import struct
>>> binascii.hexlify(struct.pack('2I', 12, 30))
b'0c0000001e000000'

Or if you want spaces to make it more readable:

>>> ' '.join(format(n,'02X') for n in struct.pack('2I', 12, 33))
'0C 00 00 00 21 00 00 00'

Python 3.6+, using f-strings (but .hex() is available and easier).

>>> ' '.join(f'{n:02X}' for n in struct.pack('2I', 12, 33))
'0C 00 00 00 21 00 00 00'
Sign up to request clarification or add additional context in comments.

Comments

11

How about his?

>>> data = struct.pack('2I',12, 30)
>>> [hex(ord(c)) for c in data]
['0xc', '0x0', '0x0', '0x0', '0x1e', '0x0', '0x0', '0x0']

The expression [item for item in sequence] is a so called list comprehension. It's basically a very compact way of writing a simple for loop, and creating a list from the result.

The ord() builtin function takes a string, and turns it into an integer that's its corresponding unicode code point (for characters in the ASCII character set that's the same as their value in the ASCII table).

Its counterpart, chr() for 8bit strings or unichr() for unicode objects do the opposite.

The hex() builtin then simply converts the integers into their hex representation.


As pointed out by @TimPeters, in Python 3 you would need to lose the ord(), because iterating over a bytes object will (already) yield integers:

Python 3.4.0a3 (default, Nov  8 2013, 18:33:56)
>>> import struct
>>> data = struct.pack('2I',12, 30)
>>> type(data)
<class 'bytes'>
>>> type(data[1])
<class 'int'>
>>>
>>> [hex(i) for i in data]
['0xc', '0x0', '0x0', '0x0', '0x1e', '0x0', '0x0', '0x0']

3 Comments

Note: in Python3, you have to lose the ord() - iterating over a bytes object gives integers.
I like this answer, but could you explain how this is working please? what do the brackets do?
@TimPeters thank you, going to update the answer accordingly.
7

You have to reformat it yourself if you want \x escapes everywhere; e.g.,

>>> import struct
>>> r = struct.pack('2I',12, 33)
>>> r
b'\x0c\x00\x00\x00!\x00\x00\x00'
>>> list(r)
[12, 0, 0, 0, 33, 0, 0, 0]
>>> print("".join("\\x%02x" % i for i in r))
\x0c\x00\x00\x00\x21\x00\x00\x00

3 Comments

Given the desired usage, I guess joining just the hexes with spaces will do
@JanDvorak, if that's what the OP wants, it's trivial to change this to do that. I'm just answering the question they asked ;-)
If we're printing it, then this will do nicely: print(*(r'\x%02x' % b for b in r), sep='')
2

In Python 3.7, bytes objects don't have an encode() method; the following code doesn't work anymore.

import struct

hex_str = struct.pack('2I',12, 30).encode('hex')

Instead of encode(), Python 3.7 code should use the hex() method, introduced in Python 3.5.

import struct

# hex_str will contain the '0c0000001e000000' string.
hex_str = struct.pack('2I',12, 30).hex()

Comments

0

There is an option to convert byte array to hex string with encode. It works for any Python from Python 2.4:

Python 2.7.12 (default, Oct 10 2016, 12:50:22)
>>> import struct
>>> struct.pack('2I',12, 30).encode('hex')
'0c0000001e000000'
>>> struct.pack('2I',12, 31).encode('hex')
'0c0000001f000000'
>>> struct.pack('2I',12, 32).encode('hex')
'0c00000020000000'
>>> struct.pack('2I',12, 33).encode('hex')
'0c00000021000000'

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.