我在了解Websocket上的数据提取的数据时遇到问题。
问题是,我不理解我们用于bitwise and
操作的十六进制代码正确的字段。(表下方的代码)
这是框架表。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
我的代码:
import struct
import math
def binary(data):
if data == 0: return "0"*8
_data = str(bin(data))[2:]
return _data.rjust(8 * math.ceil(data / 255),"0")
data = b"x81x8crx06yxe2nix17x8cherx8bbhCxd3"
header, = struct.unpack("!H",data[:2])
data = data[2:]
# HERE #
FIN = ( header >> 15 ) & 0x01 # <-
RSV1 = ( header >> 14 ) & 0x01
RSV2 = ( header >> 13 ) & 0x01
RSV3 = ( header >> 12 ) & 0x01
OPCODE = ( header >> 8 ) & 0x0F
MASK = ( header >> 7 ) & 0x01
LEN = ( header >> 0 ) & 0x7F
print(binary(OPCODE))
我们如何知道使用特定的十六进制代码?( 0x01
, 0x0F
, 0x7F
)那背后的逻辑是什么?
感谢大家。
那些特定的十六进制代码是普通的位掩码。可以从您提供的表中轻松确定它们(RFC 6455-基本框架协议)。
OPCODE
的解释:
- 位置:位4、5、6、7
- 长度:4Bits
为了提取OPCODE
,您必须进行位操作。首先,您必须在8乘8乘right shift
(因为您决定使用!H
将框架分为未签名的短裤)。在您的代码中,这是由:
header >> 8
在这一点上,四个OPCODE
位的位置从位12到15。但是,从8到11的位仍然包含不必要的数据。因此,您必须使用适当的掩码进行bitwise and
操作。在这种情况下,蒙版包含4个(OPCODE
的长度)左最低位:
Mask: 0000000000001111b (0x0F)
Value: 00000000xxxxxxxxb
& ---------- BITWISE AND ---------
Result: 000000000000xxxxb
可以类似地确定LEN
的掩码。长度为7位,因此掩码为01111111b
(十六进制中的0x7F
)。