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.

Asked By: frank

||

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'
Answered By: furas

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'
Answered By: lamsal
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.