I have bytes in Python: b'P\xf3g9\xea\xc3'
I know that this is an IP address and I know how to convert it to one (this is based on BitTorrent specification -> "the peers value may be a string consisting of multiples of 6 bytes. First 4 bytes are the IP address and last 2 bytes are the port number. All in network (big endian) notation."):
import socket import struct p = b'P\xf3g9\xea\xc3' print(f'peer {p}: bytes IP: {p[:4]}; bytes PORT: {p[4:]}') # > peer b'P\xf3g9\xea\xc3': bytes IP: b'P\xf3g9'; bytes PORT: b'\xea\xc3' print('IP', socket.inet_ntoa(p[:4])) # -> IP 80.243.103.57 # > - big-endian; H - unsigned short print('PORT', struct.unpack(">H", p[4:])[0]) # -> PORT 60099 I'm struggling to understand how this works? Ideally I would like to understand how to convert bytes to the IP address by hand.
Some questions that I have:
- what is the leading
Pin bytes? - how to transform this represntation (i assume it's hex?) to base 2?
- I think I understand
\xf3-> that translates to243. What abaoutg9?
Would be great if some one could explain or point somewhere where I can read more about it.
bytesobject is an integer.bytesand String and Bytes literals. BTW welcome to Stack Overflow! Check out the tour.Pandg9are bytes: 0x50 and 0x67 0x39. They just happen to be representable as text.g9translates to hex6739, or in decimal109,57. Python prints high ASCII codes as escaped hex sequences, but lower codes need no escaping.intobject, but that is a conversion that happens on the fly. I think it was due to it being "usually" what you want, although there is a PEP to add methods to return a bytes object representing an individual byte. Slices have always returned bytes