2

b8ビットのバイトが与えられると、次の式はb「スワップされた」ビットを返します(0と7がスワップされ、1と6がスワップされますなど)。

(b * 0x0202020202 & 0x010884422010) % 1023

このハックを実装する関数がある場合、つまり

def reverseBits(b):
    return (b * 0x0202020202 & 0x010884422010) % 1023

それから私はオーバーフローを取得します:

OverflowError:「long」をインデックスサイズの整数に収めることができません

Pythonでビットスワッピングハックを実装するにはどうすればよいですか?

4

2 に答える 2

3

これは期待どおりに機能するようです。

def sb(b):
    return (b * 0x0202020202 & 0x010884422010) % 1023

def harness(i):
    print '{:4}: {} -> {}'.format(i,bin(i)[2:].zfill(8),bin(sb(i))[2:].zfill(8))    

for i in range(256):
    harness(i)

プリント:

   0: 00000000 -> 00000000
   1: 00000001 -> 10000000
   2: 00000010 -> 01000000
   3: 00000011 -> 11000000
   4: 00000100 -> 00100000
   5: 00000101 -> 10100000
   6: 00000110 -> 01100000
   ...
 248: 11111000 -> 00011111
 249: 11111001 -> 10011111
 250: 11111010 -> 01011111
 251: 11111011 -> 11011111
 252: 11111100 -> 00111111
 253: 11111101 -> 10111111
 254: 11111110 -> 01111111
 255: 11111111 -> 11111111

このアルゴリズム(およびその他)はここにあります。前述のように、この方法はBYTEでのみ機能するため、より大きなビットパターンには別の方法を使用する必要があります。

編集

ところで:文字列操作を使用することで、オーバーフローや数学の問題を恐れることなく、より大きなビットフィールドに対してビット反転を行うことができます。

>>> w=32
>>> s=bin(1234567)[2:].zfill(w)
>>> rb=s[::-1]
>>> s
'00000000000100101101011010000111'
>>> rb
'11100001011010110100100000000000'

次に、次のようにintに変換し直します。

int(rb,2)
于 2012-07-30T16:24:25.273 に答える
0

あなたの場合の問題は、bが単なる数字ではなく1文字の文字列であるということのようです。したがって、乗算によって、非常に大きな配列が作成されます。入力データ(私が推測するファイルから取得)をstruct.unpack()するか、以下の例のようにord()とchr()を使用することをお勧めします。

確かに最速の解決策ではありませんが、私が知る限り、それは機能します。

def rev(x):
    return chr((ord(x) * 0x0202020202  & 0x010884422010) % 1023)

if __name__ == "__main__":
    with open("reverse_testfile", "wb") as o:
        with open("testfile", "rb") as f:
            o.write(''.join(map(rev, f.read())))
于 2012-07-30T17:51:54.250 に答える