13

I'm trying to print my hex out in another way...

First I'm converting this (bytestring is the name of the variable):

b'\xff\x00\xff\xff\xff'

to hex,

print(bytestring.hex())

which outputs:

ff00ffffff

but I've been trying for a while to get it to output this:

ff 00 ff ff ff

but no luck.

Any suggestions? Cheers!


Update:

stringdata = f.read(5)
print(stringdata)
#b'\xff\x00\xff\xff\xff'

readHex = " ".join(["{:02x}".format(x) for x in stringdata.hex()])
# ValueError: Unknown format code 'x' for object of type 'str'
pault
  • 41,343
  • 15
  • 107
  • 149
chxevsny
  • 133
  • 1
  • 1
  • 5
  • 1
    Possible duplicate of [What is the most "pythonic" way to iterate over a list in chunks?](https://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-to-iterate-over-a-list-in-chunks) or [Split string every nth character?](https://stackoverflow.com/questions/9475241/split-string-every-nth-character) – pault Aug 22 '18 at 20:12
  • b'\xff\x00\xff\xff\xff\' is a syntax error: one backslash too many in the end – Jean-François Fabre Aug 22 '18 at 20:14
  • @pault: if you consider the intermediate step of the hex string, yes it may be a dupe, but for the whole problem it isn't – Jean-François Fabre Aug 22 '18 at 20:15
  • sure- I was thinking `btyestring = str(b'\xff\x00\xff\xff\xff').encode('hex')` and then you can do `" ".join([btyestring[i:i+2] for i in range(0, len(btyestring), 2)])` @Jean-FrançoisFabre – pault Aug 22 '18 at 20:17

4 Answers4

15

In Python 3.8+, hex function has an optional argument splitter.

>>> print(b'\xff\x00\xff\xff\xff'.hex(' '))
'ff 00 ff ff ff'

And you can split the hex string with any character you want.

>>> print(b'\xff\x00\xff\xff\xff'.hex(':'))
'ff:00:ff:ff:ff'
PX.Liu
  • 171
  • 1
  • 7
  • 2
    There's a 2nd parameter that sets bytes per separator, the default is 1. If you make it negative it counts separators from the right, instead of the left. [docs: hex\(\[sep\[, bytes_per_sep\]\]\)](https://docs.python.org/3/library/stdtypes.html#bytes.hex) – ninMonkey Jul 01 '20 at 05:36
12

just convert your array of bytes to hex strings, and join the result with space:

>>> d=b'\xff\x00\xff\xff\xff'
>>> " ".join(["{:02x}".format(x) for x in d])
'ff 00 ff ff ff'

note that " ".join("{:02x}".format(x) for x in d) would also work, but forcing the list creation is faster as explained here: Joining strings. Generator or list comprehension?

In python 2, bytes is str so you have to use ord to get character code

>>> " ".join(["{:02x}".format(ord(x)) for x in d])
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

You can iterate over the byte string and get a series of bytes in python. These bytes are represented as integers. You then convert them back to hex strings and join them all together with a space between each hex string.

>>> a = b'\xff\x00\xff\xff'
>>> print( ' '.join( '%02x' % x for x in a ) )
'ff 00 ff ff'

Or using format in python3:

>>> a = b'\xff\x00\xff\xff'
>>> print( ' '.join( '{:02x}'.format(x) for x in a ) )
'ff 00 ff ff'
Jon Sorenson
  • 136
  • 5
  • 2
    How is this different than the other answer? – pault Aug 22 '18 at 20:18
  • It's not, I was adding it at the same time as Jean-Francois's answer. I agree with him that joining a list comprehension is probably faster that joining a generator comprehension. But I like the elegance of generator comprehensions in a function call (if you know the list doesn't have many elements). – Jon Sorenson Aug 22 '18 at 20:21
1

You can convert to a string:

bytestring = str(b'\xff\x00\xff\xff\xff').encode('hex')
print(bytestring)
#ff00ffffff

Then iterate over it in chunks of 2, and join the chunks with a space:

print(" ".join([bytestring[i:i+2] for i in range(0, len(bytestring), 2)]))
#'ff 00 ff ff ff'
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
pault
  • 41,343
  • 15
  • 107
  • 149
  • Not in Python 3.8: `LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs` – Alexis May 31 '20 at 18:21