Converting integers to bytes – how does the calculation work
Question:
I am trying to use Python bytes methods to convert integers to bytes.
I know there are different approaches to do this in Python, but I would like to do this using just the bytes method, which requires to understand how this is done using basic calculation.
As an example I have a function that converts integers to single byte:
def int_to_byte(b):
if b > 0 or b < 255:
return bytes([b])
Above function is easy since this converts a int between 0 and 255 to a single byte.
But I also would like to have following functions which converts a int to two bytes and to four bytes.
def int_to_2bytes(b):
if b > 0 or b < 65335:
return bytes([b2, b1])
Note that b2 and b1 needs to be within 0 to 255 only.
For example if I want to convert 3000 to 2 bytes using the above function I can do something like this:
def int_to_2bytes(b):
if b > 0 or b < 65335:
return bytes([b//256, b-(b//256*256)])
int_to_2bytes(3000)
b'x0bxb8'
The above gives me the correct output.
But I am now stuck what calculations to to put in to convert integers to get output as 4 bytes – something like this:
def int_to_4bytes(b):
if b > 0 or b < 4294967295:
return bytes([b3, b2, b1, b0])
How do I calculate b3, b2, b1 and b0 so that these fall within the range of 0 to 255 which then bytes method will return 4 byte back.
I would like to do this using bytes method only, I know I can do this using the struct.pack or something like this: (3000).to_bytes(4, byteorder=’big’).
Instead of using struct or to_bytes, I would like to know how I can calculate this myself using bytes method.
I manage to also solve using the following Python function:
def int_to_bytes(b):
result = []
while b > 0:
tmp = divmod(b, 256)
result.insert(0, tmp[1])
b = tmp[0]
return bytes(result)
Any help will be appreciated on this.
Answers:
You have to do similar to calculation on paper.
You have to loop and get modulo 256, and divide by 256, and repeat it on result.
def int_to_bytes(val):
data = []
while val > 0:
b = val % 256
val = val // 256
data.insert(0, b)
return bytes(data)
print( int_to_bytes(127) ) # b'x7f'
print( int_to_bytes(3000) ) # b'x0bxb8'
print( int_to_bytes(985983) ) # b'x0fx0bx7f'
print( int_to_bytes(184553088) ) # b'x0bx00x0ex80'
As you mentioned above :
def int_to_2bytes(b):
if b > 0 or b < 65335: # if b > 0 and b <= 65335: (corrected)
return bytes([b//256, b-(b//256*256)])
This can be rewritten as:
def int_to_2bytes(b):
if b > 0 and b < 256**2:
return bytes([(b//256**1)-(b//256**2*256),
(b//256**0)-(b//256**1*256)])
For int_to4bytes
:
def int_to_4bytes(b):
if b > 0 and b < 256**4:
return bytes([(b//256**3)-(b//256**4*256),
(b//256**2)-(b//256**3*256),
(b//256**1)-(b//256**2*256),
(b//256**0)-(b//256**1*256)])
Following the same pattern, for int_to_nbytes
:
def int_to_nbytes(b, n):
if b > 0 and b < 256**n:
return bytes([b//256**(n-1-i) - b//256**(n-i)*256 for i in range(n)])
print(int_to_nbytes(3000, 4)) # b'x00x00x0bxb8'
print(int_to_nbytes(3000, 8)) # b'x00x00x00x00x00x00x0bxb8'
I am trying to use Python bytes methods to convert integers to bytes.
I know there are different approaches to do this in Python, but I would like to do this using just the bytes method, which requires to understand how this is done using basic calculation.
As an example I have a function that converts integers to single byte:
def int_to_byte(b):
if b > 0 or b < 255:
return bytes([b])
Above function is easy since this converts a int between 0 and 255 to a single byte.
But I also would like to have following functions which converts a int to two bytes and to four bytes.
def int_to_2bytes(b):
if b > 0 or b < 65335:
return bytes([b2, b1])
Note that b2 and b1 needs to be within 0 to 255 only.
For example if I want to convert 3000 to 2 bytes using the above function I can do something like this:
def int_to_2bytes(b):
if b > 0 or b < 65335:
return bytes([b//256, b-(b//256*256)])
int_to_2bytes(3000)
b'x0bxb8'
The above gives me the correct output.
But I am now stuck what calculations to to put in to convert integers to get output as 4 bytes – something like this:
def int_to_4bytes(b):
if b > 0 or b < 4294967295:
return bytes([b3, b2, b1, b0])
How do I calculate b3, b2, b1 and b0 so that these fall within the range of 0 to 255 which then bytes method will return 4 byte back.
I would like to do this using bytes method only, I know I can do this using the struct.pack or something like this: (3000).to_bytes(4, byteorder=’big’).
Instead of using struct or to_bytes, I would like to know how I can calculate this myself using bytes method.
I manage to also solve using the following Python function:
def int_to_bytes(b):
result = []
while b > 0:
tmp = divmod(b, 256)
result.insert(0, tmp[1])
b = tmp[0]
return bytes(result)
Any help will be appreciated on this.
You have to do similar to calculation on paper.
You have to loop and get modulo 256, and divide by 256, and repeat it on result.
def int_to_bytes(val):
data = []
while val > 0:
b = val % 256
val = val // 256
data.insert(0, b)
return bytes(data)
print( int_to_bytes(127) ) # b'x7f'
print( int_to_bytes(3000) ) # b'x0bxb8'
print( int_to_bytes(985983) ) # b'x0fx0bx7f'
print( int_to_bytes(184553088) ) # b'x0bx00x0ex80'
As you mentioned above :
def int_to_2bytes(b):
if b > 0 or b < 65335: # if b > 0 and b <= 65335: (corrected)
return bytes([b//256, b-(b//256*256)])
This can be rewritten as:
def int_to_2bytes(b):
if b > 0 and b < 256**2:
return bytes([(b//256**1)-(b//256**2*256),
(b//256**0)-(b//256**1*256)])
For int_to4bytes
:
def int_to_4bytes(b):
if b > 0 and b < 256**4:
return bytes([(b//256**3)-(b//256**4*256),
(b//256**2)-(b//256**3*256),
(b//256**1)-(b//256**2*256),
(b//256**0)-(b//256**1*256)])
Following the same pattern, for int_to_nbytes
:
def int_to_nbytes(b, n):
if b > 0 and b < 256**n:
return bytes([b//256**(n-1-i) - b//256**(n-i)*256 for i in range(n)])
print(int_to_nbytes(3000, 4)) # b'x00x00x0bxb8'
print(int_to_nbytes(3000, 8)) # b'x00x00x00x00x00x00x0bxb8'