Python Forum

Full Version: How to understand the byte notation in python3
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey, I am trying to learn low-level stuff in py3 for some crypto project, and it is pretty hard so far.

In [63]: int(b'\x12AY5'.hex(),16)
Out[63]: 306272565 #Value of some weird byte 

In [64]: int('11111111', 2) #Highest possible val of one byte afaik
Out[64]: 255


So the first question is how this byte can have such a big value, what is this notation 'AY'? I am also dealing with notations like 'x9b;', 'x16p0?', 'x17D%', and similar.

And the second question is why this gives me another value for the same byte, seems like this hex() method was wrong somehow?:
In [65]: int.from_bytes(b'\x12AY5', byteorder='little')
Out[65]: 895041810
#In [63]: int(b'\x12AY5'.hex(),16)
#Out[63]: 306272565 
It's not a single byte, it's a bytes object which can hold several bytes. When printed, if the byte is in the ASCII range, it shows the ASCII character. If the byte is not in ASCII, it shows the value with 2 hexadecimal digits. Your object has 4 bytes inside. As an example, to break down your string into the component bytes in character, decimal, and hex form:

>>> for byte in b'\x12AY5':
...  print(f"{repr(chr(byte)):>6s} - {byte} - {byte:x}")
...
'\x12' - 18 - 12
   'A' - 65 - 41
   'Y' - 89 - 59
   '5' - 53 - 35
As it's not a single byte, you have a choice of what order if you want to assemble it into a single 32-bit decimal.


12 41 59 35 => 306272565
35 59 41 12 => 895041810
Okay, thank you for your answer.
You have made it very clear but this points me to another issue - How I am supposed to know if some byte is a part of another one? It looks tricky:

In [75]: bstr = b'r\xd4M\xdb\xbd\xddp' 

In [76]: [x for x in bstr]
Out[76]: [114, 212, 77, 219, 189, 221, 112] #MESS
Is there some pythonic way to list all byte-objects one by one with the correct int value?
I think the way you've done it above is fine. Bytes were the original str class in python before python3, so it defaults to printing the string representation. If you don't mind viewing it as hex then maybe:

>>> bstr = b'r\xd4M\xdb\xbd\xddp'
>>> bstr.hex(sep=",")
'72,d4,4d,db,bd,dd,70'
But your listcomp to show it as decimal is perfectly good.