Pythonの24ビットストリームは正しい値を与えていませんか?

私は3文字をASCIIバイナリ表記に変換しています。最初の文字は16桁、2桁目は8桁、最後はそのまま残ります。したがって、24ビットストリームが設定されているときは最初の8ビットplacesは最初の文字を表し、次の8は中間の文字を表し、最後の文字は最後の文字を表します。ここに私のコードです:

# create a block for the word 'Ozy'
bk1 = (ord('O')<<16) + (ord('z')<<8) + (ord('y'))
# Now take off the encryption for the block
cbk1 = ((chr(bk1>>16)) + (chr(bk1>>8)) + (chr(bk1&0xFF)))
# output of cbk1 is: 'O\u4f7ay'

問題がどこにあるのか、最初の文字は O として解読され、最後の文字は正しいだけでなく y でしたが、何らかの理由で z のものどうしましたか?

2
追加された 編集された
ビュー: 1

3 答え

This happens because you forgot to filter-out the bits from the first letter!
Indeed the ASCII value for the 2nd letter, 'z', shows as '7a', but as you see it has '4f' (i.e. the ASCII for 'O'), in front of it. Try something like:
cbk1 = ((chr(bk1>>16)) + (chr((bk1 & 0xFF00)>>8) ) + (chr(bk1&0xFF)))

warvariuc の答えで指摘されているように、Pythonのstructモジュールは、さまざまな形式のレコードのパッキングとアンパックを管理するのに役立ちますが、Pythonの学習の現時点では、明示的なビットワイズ操作に固執する。

1
追加された

Looks like you're missing an & 0xff:

cbk1 = ((chr(bk1>>16)) + (chr((bk1>>8) & 0xff)) + (chr(bk1&0xFF)))

正しい答えが得られます。あなたが最初の文字で設定されたビット(16ビットシフトされた)がまだそこに残るため、後で再シフトするときにも上位ビットをマスクする必要があります。

1
追加された
>>> import struct
>>> a = chr(0) + 'Ozy' # make the data 4 byte long
>>> x = struct.unpack('>I', a)[0] # convert byte data into unsigned integer of 4 bytes
>>> hex(x) # it should be 3 bytes long, because first byte was 0x00
'0x4f7a79'
>>> a = struct.pack('>I', x)[1:] # pack the integer back to bytes and throw away the left most 0x00 byte
>>> a
'Ozy'
>>> 
0
追加された