user2212461 user2212461 - 3 months ago 7
Python Question

Why does struct.pack return these values?

I have an array of signed 16bit integers that I want to convert to a little endian byte string using struct.pack in python. But I don't understand, what values struct.pack returns. Here's an example:

>>> bytestr = struct.pack('<9h',*[45, 70, 33, 38, -6, 26, 34, 46, 57])
>>> bytestr
>>>> '-\x00F\x00!\x00&\x00\xfa\xff\x1a\x00"\x00.\x009\x00'


Why are there all these special characters, like '!' or '&'? Shouldn't it be only a 2 character string for each byte?

Answer

When Python shows you a representation of a string, it'll always try to show you printable text where possible. -, F, !, &, etc. are printable ASCII characters for the given bytes.

The output is otherwise entirely correct.

  • 45, as a little-endian byte string, is represented as 0x2D 0x00 hexademimal (45 00 in decimal), but the 0x2D byte value is also the - character in the ASCII character set.

  • 70 becomes 0x46 0x00, and 0x46 is the letter F in ASCII.

  • 33 becomes 0x21 0x00, and 0x21 is !

etc.

If you wanted to verify the values, you could print the hexadecimal representation:

>>> bytestr.encode('hex')
'2d00460021002600faff1a0022002e003900'

or you could convert to a bytearray() object, then to a list, to get a list of integers in the range 0-255:

>>> list(bytearray(bytestr))
[45, 0, 70, 0, 33, 0, 38, 0, 250, 255, 26, 0, 34, 0, 46, 0, 57, 0]

These are just different ways of showing you what exact values are present in that byte string.

Comments