web-dev-qa-db-ja.com

Pythonで32ビット整数をバイトスワップする方法は?

次の例をご覧ください。

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

swap32-function()とは何ですか?理想的には組み込みツールを使用して、Pythonでintをバイトスワップする方法はありますか?

17
Patrick B.

1つの方法は、 struct モジュールを使用することです:

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

まず、一方のエンディアンを使用して整数をバイナリ形式にパックし、次にもう一方を使用して整数をアンパックします(エンディアンを交換するだけなので、使用する組み合わせは関係ありません)。

22
Carsten

ビッグエンディアンとは、32ビットintのレイアウトが最上位バイトを最初に持つことを意味し、

例えば0x12345678にはメモリレイアウトがあります

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

一方、リトルエンディアンでは、メモリレイアウトは

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

したがって、ビットマスキングとシフトを使用して、それらの間で変換するだけです。

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

python 3.2から、次のように関数swap32()を定義できます。

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

バイトの配列を使用して値を表し、整数への変換中にエンディアンを変更してバイトの順序を逆にします。

11
Artem Zankovich