简体   繁体   English

如何在 python 中字节交换 32 位 integer?

[英]How to byte-swap a 32-bit integer in python?

Take this example:举个例子:

i = 0x12345678
print("{:08x}".format(i))
   # shows 12345678
i = swap32(i)
print("{:08x}".format(i))
   # should print 78563412

What would be the swap32-function() ? swap32-function()是什么? Is there a way to byte-swap an int in python, ideally with built-in tools?有没有办法在 python 中对int进行字节交换,最好使用内置工具?

One method is to use the struct module:一种方法是使用struct模块:

def swap32(i):
    return struct.unpack("<I", struct.pack(">I", i))[0]

First you pack your integer into a binary format using one endianness, then you unpack it using the other (it doesn't even matter which combination you use, since all you want to do is swap endianness).首先,您使用一种字节序将整数打包成二进制格式,然后使用另一种将其解包(使用哪种组合并不重要,因为您要做的只是交换字节序)。

Big endian means the layout of a 32 bit int has the most significant byte first,大端意味着 32 位 int 的布局首先具有最高有效字节,

eg 0x12345678 has the memory layout例如 0x12345678 具有内存布局

msb             lsb
+------------------+
| 12 | 34 | 56 | 78|
+------------------+

while on little endian, the memory layout is而在小端,内存布局是

lsb             msb
+------------------+
| 78 | 56 | 34 | 12|
+------------------+

So you can just convert between them with some bit masking and shifting:因此,您可以通过一些位掩码和移位在它们之间进行转换:

def swap32(x):
    return (((x << 24) & 0xFF000000) |
            ((x <<  8) & 0x00FF0000) |
            ((x >>  8) & 0x0000FF00) |
            ((x >> 24) & 0x000000FF))

From python 3.2 you can define function swap32() as the following:从 python 3.2 你可以定义函数 swap32() 如下:

def swap32(x):
    return int.from_bytes(x.to_bytes(4, byteorder='little'), byteorder='big', signed=False)

It uses array of bytes to represent the value and reverses order of bytes by changing endianness during conversion back to integer.它使用字节数组来表示值并通过在转换回整数期间更改字节顺序来反转字节顺序。

Maybe simpler use the socket library.也许更简单地使用套接字库。

from socket import htonl

swapped = htonl (i)
print (hex(swapped))

that's it.就是这样。 this library also works in the other direction with ntohl这个库也适用于 ntohl 的另一个方向

The array module provides a byteswap() method for fixed sized items. array模块为固定大小的项目提供了byteswap()方法。 The array module appears to be in versions back to Python 2.7 array 模块的版本似乎可以追溯到 Python 2.7

array.byteswap() “Byteswap” all items of the array. array.byteswap() “字节交换”数组的所有项目。 This is only supported for values which are 1, 2, 4, or 8 bytes in size;这仅支持大小为 1、2、4 或 8 字节的值;

Along with the fromfile() and tofile() methods, this module is quite easy to use:fromfile()tofile()方法一起,这个模块非常容易使用:

import array

# Open a data file.
input_file = open( 'my_data_file.bin' , 'rb' )

# Create an empty array of unsigned 4-byte integers.
all_data = array.array( 'L' )

# Read all the data from the file.
all_data.fromfile( input_file , 16000 )               # assumes the size of the file

# Swap the bytes in all the data items.
all_data.byteswap( )

# Write all the data to a new file.
output_file = open( filename[:-4] + '.new' , 'wb' )    # assumes a three letter extension
all_data.tofile( output_file )

# Close the files.
input_file.close( )
output_file_close( )

The above code worked for me since I have fixed-size data files.上面的代码对我有用,因为我有固定大小的数据文件。 There are more Pythonic ways to handle variable length files.有更多 Pythonic 方式来处理可变长度文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM