我在理解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"\x81\x8c\r\x06y\xe2ni\x17\x8che\r\x8bbhC\xd3"
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
)它背后的逻辑是什么?
感谢大家。
答案 0 :(得分:1)
那些特定的十六进制代码是普通的位掩码。可以从您提供的表格(RFC 6455 - Base Framing Protocol)轻松确定它们。
OPCODE
的解释:
为了提取OPCODE
,你必须进行位操作。
首先,您必须按right shift
加8(因为您决定使用!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
)。