Integers represent whole numbers with arbitrary precision. Bytes represent immutable sequences of single bytes (0 – 255), which you can use for binary data. If you are doing data serialization, network communication, cryptography, or writing binary files, you need conversion from one format to another.
Converting int to bytes
The most efficient way to convert an integer to bytes is to use the int.to_bytes() method.
Behind the scenes, the following process happens:
- Python first converts an integer to binary.
- Binary is grouped into chunks of 8 bits (1 byte). Each 8-bit chunk becomes a byte.
- We set the ‘big’ or “little” endian. There is also an optional signed argument, but we did not use it here. By default, it is False.
- When we print the bytes, they will be converted to hex for better readability. Since 1 byte = 2 hex digits, our output will be bytes, but for better interpretation, they will be converted to hex.
Let’s convert an integer to a 2-byte big-endian format.
# Unsigned 16-bit big-endian main_int = 1028 converted_byte = (main_int).to_bytes(2, 'big') print(converted_byte) # Output: b'\x04\x04'
In the above code, we passed two arguments to the .to_bytes() method:
- 2: It is the number of bytes to use. Since the above input is a 16-bit number, it means 2 bytes.
- big: It means the most significant bytes will come first. If you pass ‘little’, it would mean the least significant byte comes first.
The final output is a byte string: b’\x04\x04′, which is a hex representation of bytes.
Let’s take another integer, 1029, and see the difference between big and little endians:
main_int = 1029 num_bytes = 2 # We want a 16-bit (2-byte) representation big_endian_bytes = main_int.to_bytes(num_bytes, 'big') little_endian_bytes = main_int.to_bytes(num_bytes, 'little') # --- Print the results --- print(f"Original Integer: {main_int}") print("-" * 30) print(f"Big-Endian Representation: {big_endian_bytes}") print(f"Little-Endian Representation: {little_endian_bytes}") print("-" * 30) # Optional: Print hex values for clarity print(f"Big-Endian Hex: 0x{big_endian_bytes.hex()}") print(f"Little-Endian Hex: 0x{little_endian_bytes.hex()}")
Output
Original Integer: 1029 ------------------------------ Big-Endian Representation: b'\x04\x05' Little-Endian Representation: b'\x05\x04' ------------------------------ Big-Endian Hex: 0x0405 Little-Endian Hex: 0x0504
Negative numbers
If you are working with negative numbers, set the signed parameter to True.
main_int = -1028 converted_byte = (main_int).to_bytes(2, 'big', signed=True) print(converted_byte) # Output: b'\xfb\xfc'
Handling large integers
If your input integer size is very large, we can compute the minimal bytes for unsigned integers.
n = 2**100 bytes_data = n.to_bytes((n.bit_length() + 7) // 8, 'big') print(bytes_data) # Output: b'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
The above output shows that we presented a big number (2**100) in 13 bytes.
Converting bytes to int
You can convert back bytes to an integer optimally using the int.from_bytes() method. It accepts bytes that we want to convert back to an integer, byteorder, which can be big or little, and signed (optional argument), which is either True or False. By default, it is False.
bytes = b'\x04\x04' # Convert bytes to int int_converted = int.from_bytes(bytes, byteorder='big') print(int_converted) # Output: 1028
And we get the converted integer 1028.
Choose big or little endian based on your data format. That’s all!