Assuming you're on at least 3.2, there's a built in for this:
int.from_bytes(bytes,byteorder, *,signed=False)...
The argument
bytesmust either be a bytes-like object or an iterable producing bytes.The
byteorderargument determines the byte order used to represent the integer. Ifbyteorderis"big", the most significant byte is at the beginning of the byte array. Ifbyteorderis"little", the most significant byte is at the end of the byte array. To request the native byte order of the host system, usesys.byteorderas the byte order value.The
signedargument indicates whether two’s complement is used to represent the integer.
## Examples:
int.from_bytes(b'\x00\x01', "big") # 1
int.from_bytes(b'\x00\x01', "little") # 256
int.from_bytes(b'\x00\x10', byteorder='little') # 4096
int.from_bytes(b'\xfc\x00', byteorder='big', signed=True) #-1024
Answer from Peter DeGlopper on Stack OverflowAssuming you're on at least 3.2, there's a built in for this:
int.from_bytes(bytes,byteorder, *,signed=False)...
The argument
bytesmust either be a bytes-like object or an iterable producing bytes.The
byteorderargument determines the byte order used to represent the integer. Ifbyteorderis"big", the most significant byte is at the beginning of the byte array. Ifbyteorderis"little", the most significant byte is at the end of the byte array. To request the native byte order of the host system, usesys.byteorderas the byte order value.The
signedargument indicates whether two’s complement is used to represent the integer.
## Examples:
int.from_bytes(b'\x00\x01', "big") # 1
int.from_bytes(b'\x00\x01', "little") # 256
int.from_bytes(b'\x00\x10', byteorder='little') # 4096
int.from_bytes(b'\xfc\x00', byteorder='big', signed=True) #-1024
Lists of bytes are subscriptable (at least in Python 3.6). This way you can retrieve the decimal value of each byte individually.
>>> intlist = [64, 4, 26, 163, 255]
>>> bytelist = bytes(intlist) # b'@\x04\x1a\xa3\xff'
>>> for b in bytelist:
... print(b) # 64 4 26 163 255
>>> [b for b in bytelist] # [64, 4, 26, 163, 255]
>>> bytelist[2] # 26
Convert a string byte to integer
Byte to integer ? why so complicated in python?
Converting integer to byte string problem in python 3
Python 2,3 Convert Integer to "bytes" Cleanly - Stack Overflow
Hi, I have a peculiar setup. I have a byte array converted to a string. It resembles something like: bytearray(b'\xfa\xff\xff\xff\xff\xff\xff....
The string arrives from a TCP socket, and I want to convert this string into a list or numpy array of integers from 0 to 255.
I am able to convert to a list resembling this: 'ff', 'ff', 'f9', 'ff', 'ff', 'ff', '00', '00', '00', '00', 'f6', 'ff', 'ff', 'ff', '00', '00', '00',...
However, using decode('utf-8') did not seem to work.
I have tried several methods with limited outcomes. For example, for loops and lambdas to iterate through each loop, trying to use int(), etc.
Since this is python 3, I get errors stating that 'Str' and list have no attribute 'decode.'
Any suggestions on making this more efficient? Some Codec function perhaps?
Answer 1:
To convert a string to a sequence of bytes in either Python 2 or Python 3, you use the string's encode method. If you don't supply an encoding parameter 'ascii' is used, which will always be good enough for numeric digits.
s = str(n).encode()
- Python 2: http://ideone.com/Y05zVY
- Python 3: http://ideone.com/XqFyOj
In Python 2 str(n) already produces bytes; the encode will do a double conversion as this string is implicitly converted to Unicode and back again to bytes. It's unnecessary work, but it's harmless and is completely compatible with Python 3.
Answer 2:
Above is the answer to the question that was actually asked, which was to produce a string of ASCII bytes in human-readable form. But since people keep coming here trying to get the answer to a different question, I'll answer that question too. If you want to convert 10 to b'10' use the answer above, but if you want to convert 10 to b'\x0a\x00\x00\x00' then keep reading.
The struct module was specifically provided for converting between various types and their binary representation as a sequence of bytes. The conversion from a type to bytes is done with struct.pack. There's a format parameter fmt that determines which conversion it should perform. For a 4-byte integer, that would be i for signed numbers or I for unsigned numbers. For more possibilities see the format character table, and see the byte order, size, and alignment table for options when the output is more than a single byte.
import struct
s = struct.pack('<i', 5) # b'\x05\x00\x00\x00'
You can use the struct's pack:
In [11]: struct.pack(">I", 1)
Out[11]: '\x00\x00\x00\x01'
The ">" is the byte-order (big-endian) and the "I" is the format character. So you can be specific if you want to do something else:
In [12]: struct.pack("<H", 1)
Out[12]: '\x01\x00'
In [13]: struct.pack("B", 1)
Out[13]: '\x01'
This works the same on both python 2 and python 3.
Note: the inverse operation (bytes to int) can be done with unpack.
From python 3.2 you can use to_bytes:
>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'
def int_to_bytes(x: int) -> bytes:
return x.to_bytes((x.bit_length() + 7) // 8, 'big')
def int_from_bytes(xbytes: bytes) -> int:
return int.from_bytes(xbytes, 'big')
Accordingly, x == int_from_bytes(int_to_bytes(x)).
Note that the above encoding works only for unsigned (non-negative) integers.
For signed integers, the bit length is a bit more tricky to calculate:
def int_to_bytes(number: int) -> bytes:
return number.to_bytes(length=(8 + (number + (number < 0)).bit_length()) // 8, byteorder='big', signed=True)
def int_from_bytes(binary_data: bytes) -> Optional[int]:
return int.from_bytes(binary_data, byteorder='big', signed=True)
That's the way it was designed - and it makes sense because usually, you would call bytes on an iterable instead of a single integer:
>>> bytes([3])
b'\x03'
The docs state this, as well as the docstring for bytes:
>>> help(bytes)
...
bytes(int) -> bytes object of size given by the parameter initialized with null bytes