如果作为服务器的客户端应该为其加密密钥重新键入密钥,我尝试将unsigned int的第一位用作标志。我想将其余的unsigned int用作正在发送的剩余数据的长度。

目前,我正在尝试此操作,但似乎没有用。

unsigned int payloadLength;
read(sock, &payloadLength, sizeof(payloadLength));
short bit = (payloadLength >> 0) & 1U; // get first bit

payloadLength &= 1UL << 0; // set first bit to 0
payloadLength = ntohl(payloadLength);

if (bit == 1)
   //rekey
else
  //read more data

重命名标志似乎设置正确,但是当尝试获取长度时,它总是以错误的数字结尾。

编辑:我应该澄清我的意思是最高有效位,而不是第一位

最佳答案

让我们看一下这段代码:

short bit = (payloadLength >> 0) & 1U; // get first bit
payloadLength &= 1UL << 0; // set first bit to 0
payloadLength = ntohl(payloadLength);

尽管以这种方式订购这些语句是完全合法的,但仍有可能无法按照您希望的方式工作。具体来说,您可能想在开始戳和探查字节之前解码有效负载以使用主机字节顺序。否则,如果您将数据从一个系统发送到另一个系统,则有可能会读回错误的位。但这并不是很难解决-只需将最后一个对payloadLength进行解码的语句移到顶部即可,如下所示:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = (payloadLength >> 0) & 1U; // get first bit
payloadLength &= 1UL << 0; // set first bit to 0

接下来,有一个关于您要尝试读取的位的问题。您似乎正在尝试读取数字的最低有效位。在这种情况下,您不需要包含任何位移,因为零位位移没有任何作用。让我们删除它们,给出以下内容:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= 1UL; // set first bit to 0

您提取数字最后一位的代码是正确的。它将屏蔽掉最低位以外的所有内容,然后将值存储在变量bit中。 (出于好奇,您是否有任何理由将其存储为short?如果您正在寻找 bool(boolean) 值“我是否需要对此重新编码?”,您可能只想使用bool并编写类似
bool reencode = (payloadLength & 1U) != 0;

不过,这取决于您。)

但是,您清除最后一位的代码不正确。现在,当你写
payloadLength &= 1UL; // set first bit to 0

您实际上正在执行与预期相反的操作-您正在清除除第一位以外的所有位。这是因为如果您将payloadLength与一个值进行“与”运算,则将payloadLength中的每一位都归零,除了1UL中等于1的位。但是,1UL在最后位置只有1位。您可能打算写类似
payloadLength &= ~1UL; // set first bit to 0

〜运算符在其中翻转掩码的位。总体而言,这将为您提供以下内容:
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= ~1UL; // set first bit to 0

我还有最后一个问题。通过以这种方式重新利用数字的最低位,您就要求有效载荷长度必须始终为偶数,因为您要利用有效载荷长度的1比特来编码是否重新键入密钥。如果您对此表示满意,那就太好了!您什么都不需要做。

另一方面,如果这是一个问题,那么您有几个选择,我将留给您选择:
  • 代替使用最低有效位,而使用最高有效位。但是,如果您尝试发送大小为231或更高的有效负载,则会导致问题。
  • 使用最低有效位,但数字的高31位代表实际有效载荷长度。要提取有效载荷长度,只需将所有内容移到一个位置即可。但是,这具有不支持大小为231或更大的有效载荷的缺点。
  • 根本不要使用这些位来编码!而是发送有效载荷长度,然后使有效载荷以 header 开头,该 header 告诉您是否进行密钥更新等。这会为每个有效载荷使用更多字节,但在将来也为您提供更大的灵活性(如果您需要发送其他标志,好吗?)

  • 希望这可以帮助!

    09-25 20:37