How to display a byte array as hex values

>>> 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

share improve this question
 
1 
' ' === '\x20''!' === '\x21' –  Jan Dvorak  Dec 27 '13 at 19:25 
 
I know but how can I get it display as a hex number, so everything is uniform? –  Siavash  Dec 27 '13 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. –  Jan Dvorak  Dec 27 '13 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 –  Siavash  Dec 27 '13 at 19:29

3 Answers

up vote 4 down vote accepted

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']
share improve this answer
 
3 
Note: in Python3, you have to lose the ord() - iterating over a bytes object gives integers. –  Tim Peters Dec 27 '13 at 19:44
1 
I like this answer, but could you explain how this is working please? what do the brackets do? –  Siavash Dec 27 '13 at 19:44
 
@TimPeters thank you, going to update the answer accordingly. –  Lukas Graf  Dec 27 '13 at 19:48
 
@Siavash sure! See my updated answer. –  Lukas Graf  Dec 27 '13 at 20:01

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
share improve this answer
 
 
Given the desired usage, I guess joining just the hexes with spaces will do –  Jan Dvorak  Dec 27 '13 at 19:34
 
@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 ;-) –  Tim Peters  Dec 27 '13 at 19:35

Try binascii.hexlify:

>>> import binascii
>>> import struct
>>> binascii.hexlify(struct.pack('2I',12,30))
b'0c0000001e000000'
>>> binascii.hexlify(struct.pack('2I',12,31))
b'0c0000001f000000'
>>> binascii.hexlify(struct.pack('2I',12,32))
b'0c00000020000000'
>>> binascii.hexlify(struct.pack('2I',12,33))
b'0c00000021000000'

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'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值