杰瑞科技汇

Python int如何转为bytes?

Of course! Converting a Python int to bytes is a common task, especially in low-level programming, cryptography, and networking. The key is to understand that an integer is just a number, and to convert it to bytes, you need to specify two things:

Python int如何转为bytes?-图1
(图片来源网络,侵删)
  1. Endianness: The order of the bytes (most significant byte first or least significant byte first).
  2. Length: The number of bytes to use. This determines the range of numbers you can represent.

Let's break down the methods, from the simplest to the most manual.

The Short Answer: Use int.to_bytes()

For most cases, the built-in int.to_bytes() method is the best and most Pythonic way.

# A positive integer
my_int = 123456
# Convert to 4 bytes, in big-endian order
bytes_big_endian = my_int.to_bytes(4, 'big')
print(f"Big-endian: {bytes_big_endian}")
# Output: Big-endian: b'\x01\xe2@'
# Convert to 4 bytes, in little-endian order
bytes_little_endian = my_int.to_bytes(4, 'little')
print(f"Little-endian: {bytes_little_endian}")
# Output: Little-endian: b'@\xe2\x01\x00'

Detailed Explanation of int.to_bytes()

The method signature is: int.to_bytes(length, byteorder, *, signed=False)

length

This is the number of bytes the resulting byte string should have. It's a required argument.

Python int如何转为bytes?-图2
(图片来源网络,侵删)
  • If the number is too large to fit in the specified number of bytes, Python will raise an OverflowError.
  • If the number is smaller than the maximum value for the given length, it will be padded with zeros at the beginning (for big-endian) or end (for little-endian).
# Number is small enough to fit in 4 bytes
small_int = 255
print(small_int.to_bytes(4, 'big')) # Padded with 3 leading zeros
# Output: b'\x00\x00\x00\xff'
# Number is too large for 2 bytes
large_int = 70000
try:
    large_int.to_bytes(2, 'big')
except OverflowError as e:
    print(e)
# Output: int too big to convert

byteorder

This specifies the order of the bytes. It's also a required argument.

  • 'big': Most significant byte (MSB) is at the beginning of the byte string. This is the network standard order.
  • 'little': Least significant byte (LSB) is at the beginning of the byte string. This is common for x86 processors.
  • 'native': Uses the native byte order of the system ('big' on big-endian systems, 'little' on little-endian systems).
  • '>': Synonym for 'big'.
  • '<': Synonym for 'little'.

signed (Optional)

This is a keyword-only argument ( in the signature). It's a boolean that indicates whether the integer should be treated as a signed value.

  • signed=False (default): The integer is treated as unsigned. This is the most common case.
  • signed=True: The integer is treated as signed (can be negative).

Important: When signed=True, you must provide a length that is sufficient to represent the negative number (typically using two's complement). Python will raise an OverflowError if the length is too small.

# Signed integer example
negative_int = -12345
# To represent -12345, we need at least 3 bytes
# Let's see what 3 bytes can hold for signed integers:
# 3 bytes = 24 bits. The range is -2^23 to 2^23 - 1, which is -8,388,608 to 8,388,607.
# -12345 is within this range.
bytes_signed = negative_int.to_bytes(3, 'big', signed=True)
print(f"Signed: {bytes_signed}")
# Output: Signed: b'\xf6\xd7\xf7'
# This is the same number, but represented in 4 bytes
bytes_signed_4 = negative_int.to_bytes(4, 'big', signed=True)
print(f"Signed (4 bytes): {bytes_signed_4}")
# Output: Signed (4 bytes): b'\xff\xf6\xd7\xf7'

Alternative Method: int.bit_length() and Bitwise Operations

If you want to understand what's happening under the hood or need more control, you can manually construct the bytes. This involves using bitwise operators (>>, &) and the bytes() constructor.

Python int如何转为bytes?-图3
(图片来源网络,侵删)

The logic is:

  1. Determine the required number of bytes.
  2. Loop, shifting the integer right by 8 bits in each iteration.
  3. In each iteration, take the lowest 8 bits using a bitwise AND with 0xff.
  4. Append these 8 bits to a list.
  5. Reverse the list if you want big-endian order.
def int_to_bytes_manual(n: int, byteorder: str = 'big') -> bytes:
    """Converts an integer to bytes manually."""
    if n == 0:
        return b'\x00'
    # Handle negative numbers by getting their two's complement representation
    if n < 0:
        n = (1 << (n.bit_length() + 1)) + n
    byte_list = []
    while n:
        byte_list.append(n & 0xff)  # Get the last 8 bits
        n >>= 8                     # Shift right by 8 bits
    # Pad to a multiple of 8 bits if necessary (though the loop handles it)
    # This is more for conceptual clarity
    if len(byte_list) == 0:
        return b'\x00'
    # Reverse for big-endian, keep as is for little-endian
    if byteorder == 'big':
        byte_list.reverse()
    return bytes(byte_list)
# Example usage
my_int = 0x12345678 # 305419896 in decimal
bytes_be = int_to_bytes_manual(my_int, 'big')
print(f"Manual Big-endian: {bytes_be.hex()}")
# Output: Manual Big-endian: 12345678
bytes_le = int_to_bytes_manual(my_int, 'little')
print(f"Manual Little-endian: {bytes_le.hex()}")
# Output: Manual Little-endian: 78563412

The Reverse: Converting Bytes to an int

The reverse operation is just as straightforward using int.from_bytes().

my_bytes = b'\x12\x34\x56\x78'
# Convert from big-endian bytes to an integer
int_from_be = int.from_bytes(my_bytes, 'big')
print(f"Integer from big-endian: {int_from_be}")
# Output: Integer from big-endian: 305419896
# Convert from little-endian bytes to an integer
int_from_le = int.from_bytes(my_bytes, 'little')
print(f"Integer from little-endian: {int_from_le}")
# Output: Integer from little-endian: 2025915346

Summary: Which Method to Use?

Method When to Use Pros Cons
int.to_bytes() Almost always. This is the standard, recommended way. - Simple, readable, and Pythonic.
- Handles endianness, signedness, and padding automatically.
- Less error-prone.
- None for standard use cases.
Manual Bitwise - Learning how it works.
- Extremely specific, non-standard requirements.
- Full control over the conversion process.
- No hidden "magic".
- Verbose and complex.
- Easy to make mistakes (e.g., off-by-one errors, handling negatives).
分享:
扫描分享到社交APP
上一篇
下一篇