我正在尝试制作一个php套接字服务器,我发现了两个函数可以屏蔽和取消屏蔽文本消息(框架)。我想我不清楚它是如何工作的。这是功能:
//encode message for transfer to client
function mask($text)
{
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if ($length <= 125)
$header = pack('CC', $b1, $length);
elseif ($length > 125 && $length < 65536)
$header = pack('CCn', $b1, 126, $length);
elseif ($length >= 65536)
$header = pack('CCNN', $b1, 127, $length);
return $header . $text;
}
//unmask incoming framed message
function unmask($text)
{
$length = ord($text[1]) & 127;
if ($length == 126) {
$masks = substr($text, 4, 4);
$data = substr($text, 8);
} elseif ($length == 127) {
$masks = substr($text, 10, 4);
$data = substr($text, 14);
} else {
$masks = substr($text, 2, 4);
$data = substr($text, 6);
}
$text = "";
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i % 4];
}
return $text;
}
我想我已经明白了:
掩码转换消息的二进制表示,并根据消息长度创建一个大小合适的帧(通过连接标头)。(通过pack()添加字节,对吗?)
取消掩码->反向过程。
我不明白的是:掩码中使用的变量$b1的目的是什么?这个代码的语法我不清楚。
$b1 = 0x80 | (0x1 & 0x0f);
用这种方式写这行有点奇怪,但下面是发生的事情;是一个二进制AND运算符,它取两个值,只返回匹配的位。0x1是二进制的00000001,0x0f是二进制的00001111。
00000001
&00001111
=00000001
因此(0x1&0x0f)仅为0x1或1。
|运算符类似于&,而是二进制OR。如果任意一方的值为1,则结果为1。0x80是01000000,所以
01000000
|00000001
=01000001
所以总的结果是0x81。为什么不直接写入$b1=0x81?我猜这段代码的作者是从一些C代码中复制的,其中0x1部分是一个变量:
byte b1 = 0x80 | (someVariable & 0x0f);
在这种情况下,二进制&0x0f确保只使用someVariable的最后4位,b1的前4位将始终为0x8(根据帧规范,这可能是必要的)。