Python 2,3 Convert Integer to "bytes" Cleanly

Question:

The shortest ways I have found are:

n = 5

# Python 2.
s = str(n)
i = int(s)

# Python 3.
s = bytes(str(n), "ascii")
i = int(s)

I am particularly concerned with two factors: readability and portability. The second method, for Python 3, is ugly. However, I think it may be backwards compatible.

Is there a shorter, cleaner way that I have missed? I currently make a lambda expression to fix it with a new function, but maybe that’s unnecessary.

Asked By: imallett

||

Answers:

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()

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'x0ax00x00x00' 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'x05x00x00x00'
Answered By: Mark Ransom

Converting an int to a byte in Python 3:

    n = 5    
    bytes( [n] )

>>> b'x05'

😉 guess that’ll be better than messing around with strings

source: http://docs.python.org/3/library/stdtypes.html#binaryseq

Answered By: Nadu

You can use the struct’s pack:

In [11]: struct.pack(">I", 1)
Out[11]: 'x00x00x00x01'

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]: 'x01x00'

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.

Answered By: Andy Hayden

I have found the only reliable, portable method to be

bytes(bytearray([n]))

Just bytes([n]) does not work in python 2. Taking the scenic route through bytearray seems like the only reasonable solution.

Answered By: alex.forencich

from int to byte:

bytes_string = int_v.to_bytes( lenth, endian )

where the lenth is 1/2/3/4…., and endian could be ‘big’ or ‘little’

form bytes to int:

data_list = list( bytes );
Answered By: Sunber

In Python 3.x, you can convert an integer value (including large ones, which the other answers don’t allow for) into a series of bytes like this:

import math

x = 0x1234
number_of_bytes = int(math.ceil(x.bit_length() / 8))

x_bytes = x.to_bytes(number_of_bytes, byteorder='big')

x_int = int.from_bytes(x_bytes, byteorder='big')
x == x_int
Answered By: retsigam
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.