杰瑞科技汇

Python little endian 是什么意思?

Of course! Let's break down "little endian" in Python, from the basic concept to practical code examples.

Python little endian 是什么意思?-图1
(图片来源网络,侵删)

What is Endianness?

At its core, endianness is the order in which a computer stores a sequence of bytes that make up a larger data type (like a 4-byte integer or an 8-byte float).

Think of it like writing a multi-digit number. You write the most significant digit first (e.g., 1 in 123 is the most significant). This is called Big-Endian.

However, computers can store these bytes in two main ways:

  • Big-Endian (Most Significant Byte First - MSB): The most significant byte is stored at the lowest memory address.

    Python little endian 是什么意思?-图2
    (图片来源网络,侵删)
    • Analogy: Writing a number from left to right (123).
    • The number 0x12345678 would be stored in memory as: [0x12, 0x34, 0x56, 0x78]
  • Little-Endian (Least Significant Byte First - LSB): The least significant byte is stored at the lowest memory address.

    • Analogy: Writing a number from right to left (321).
    • The number 0x12345678 would be stored in memory as: [0x78, 0x56, 0x34, 0x12]

Why does this matter? When you read data from a file, a network socket, or hardware, you need to know the endianness of the source. If you read 4 bytes expecting a big-endian number but they are actually little-endian, you will get the wrong value.


Little Endian in Python

Python has built-in tools to handle endianness, primarily through the struct module and the int.from_bytes() / int.to_bytes() methods.

Key Takeaway:

Modern Intel/AMD x86 and x64 processors (which most desktop and server computers use) are natively little-endian. Therefore, when you work with integers and bytes in Python on these systems, you are often dealing with little-endian data by default.

Python little endian 是什么意思?-图3
(图片来源网络,侵删)

Practical Examples with the struct Module

The struct module is perfect for converting between Python values (like integers) and C-style byte data. It uses a format string to specify the data types and endianness.

The format string character for endianness is:

  • <: Little-endian
  • >: Big-endian
  • Native (whatever the system's native format is, which is usually little-endian on x86/x64)

Let's use the number 305419896 (which is 0x12345678 in hexadecimal).

import struct
# The number we want to pack and unpack
number = 305419896  # This is 0x12345678
# --- Little Endian Example ---
# The format string '<I' means:
# <: Little-endian
# I: Unsigned Integer (4 bytes)
little_endian_bytes = struct.pack('<I', number)
print(f"Packed as Little-Endian: {little_endian_bytes.hex(' ')}")
# Expected Output: 78 56 34 12
# Notice the bytes are in reverse order of the hex representation.
# Now, let's unpack them back into an integer
unpacked_number = struct.unpack('<I', little_endian_bytes)[0]
print(f"Unpacked from Little-Endian: {unpacked_number}")
# Expected Output: 305419896
print("-" * 20)
# --- Big Endian Example (for comparison) ---
# The format string '>I' means:
# >: Big-endian
# I: Unsigned Integer (4 bytes)
big_endian_bytes = struct.pack('>I', number)
print(f"Packed as Big-Endian:    {big_endian_bytes.hex(' ')}")
# Expected Output: 12 34 56 78
# Notice the bytes are in the same order as the hex representation.
# Unpack them back
unpacked_number_big = struct.unpack('>I', big_endian_bytes)[0]
print(f"Unpacked from Big-Endian:    {unpacked_number_big}")
# Expected Output: 305419896

Practical Examples with int.from_bytes() and int.to_bytes()

This is a more modern and often simpler way to work with integers and bytes.

# The number we want to convert
number = 305419896  # 0x12345678
# --- Convert an integer to little-endian bytes ---
# The 'byteorder' argument is 'little' or 'big'
# 'length' is the size of the integer in bytes
little_endian_bytes = number.to_bytes(length=4, byteorder='little')
print(f"Converted to Little-Endian bytes: {little_endian_bytes.hex(' ')}")
# Expected Output: 78 56 34 12
# --- Convert little-endian bytes back to an integer ---
# We need to know the byte order was 'little' to read it correctly
recovered_number = int.from_bytes(little_endian_bytes, byteorder='little')
print(f"Recovered from Little-Endian bytes: {recovered_number}")
# Expected Output: 305419896
print("-" * 20)
# --- Convert an integer to big-endian bytes (for comparison) ---
big_endian_bytes = number.to_bytes(length=4, byteorder='big')
print(f"Converted to Big-Endian bytes:    {big_endian_bytes.hex(' ')}")
# Expected Output: 12 34 56 78
recovered_number_big = int.from_bytes(big_endian_bytes, byteorder='big')
print(f"Recovered from Big-Endian bytes:    {recovered_number_big}")
# Expected Output: 305419896

A Real-World Scenario: Reading a Binary File

Imagine you have a file data.bin that contains a 4-byte unsigned integer in little-endian format. You can read it like this:

import struct
# Let's create the dummy file first for this example
with open('data.bin', 'wb') as f:
    # Write the number 1000 in little-endian format
    f.write(struct.pack('<I', 1000))
# --- Now, let's read it back ---
print("Reading from data.bin...")
try:
    with open('data.bin', 'rb') as f:
        # Read exactly 4 bytes from the file
        byte_data = f.read(4)
    # Check if we read 4 bytes
    if len(byte_data) == 4:
        # Unpack the 4 bytes as a little-endian unsigned integer
        number = struct.unpack('<I', byte_data)[0]
        print(f"The number read from the file is: {number}")
    else:
        print("Error: Could not read 4 bytes from the file.")
except FileNotFoundError:
    print("Error: data.bin not found.")
# Expected Output:
# Reading from data.bin...
# The number read from the file is: 1000

Summary

Task Method Example (Little Endian)
Pack (int -> bytes) struct.pack() struct.pack('<I', 305419896)
Unpack (bytes -> int) struct.unpack() struct.unpack('<I', b'xV4\x12')[0]
Convert to Bytes int.to_bytes() to_bytes(4, 'little')
Convert from Bytes int.from_bytes() int.from_bytes(b'xV4\x12', 'little')

Remember to always check the documentation or specification of the data source (file format, network protocol, hardware manual) to know whether it uses little-endian or big-endian.

分享:
扫描分享到社交APP
上一篇
下一篇