在 unsigned int 中使用第一位作为标志
Using first bit as a flag in an unsigned int
如果作为服务器的客户端应该为他们的加密密钥重新设置密钥,我正在尝试使用 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
rekey 标志似乎设置正确,但在尝试获取长度时,它总是以错误的数字结束。
编辑:我应该澄清我的意思是最高有效位,而不是第一位
payloadLength &= 1UL << 0;
会将除第一个以外的所有位归零。
payloadLength &= ~1UL;
会将第一位归零。
让我们看一下这段代码:
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
接下来,有一个问题是关于您尝试读取的是哪一位。看起来您正在尝试读取数字的 least-significant 位。如果是这种情况,您不需要包含任何移位,因为按零位移位没有任何效果。让我们删除那些,给这个:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= 1UL; // set first bit to 0
您提取数字最后一位的代码是正确的。它会屏蔽除最低位以外的所有内容,然后将值存储在变量 bit
中。 (出于好奇,是否有任何理由将其存储为 short
?如果您正在寻找布尔值 "do I need to reencode this?,",您可能只想使用 bool
并写一些东西喜欢
bool reencode = (payloadLength & 1U) != 0;
不过,这由您决定。)
但是,您清除最后一位的代码不正确。现在,当你写
payloadLength &= 1UL; // set first bit to 0
你实际上做的与你的意图相反 - 你正在清除每一位 除了第一个。那是因为如果您将 payloadLength
与一个值进行 AND 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 位来编码是否重新加密。如果您对此表示满意,那就太好了!您无需执行任何操作。
另一方面,如果这是个问题,您有几个选择,我会留给您 select 来自:
不使用 least-significant 位,而是使用 most-significant 位。但是,如果您尝试发送大小为 231 或更大的有效载荷,这将导致问题。
使用least-significant位,但让数字的高31位代表实际负载长度。要提取有效负载长度,只需将所有内容移动一个位置即可。不过,它的缺点是不支持大小为 231 或更大的有效载荷。
根本不要使用这些位来编码!相反,发送有效载荷长度,然后让有效载荷以 header 开头,告诉您是否重新加密等。这每个有效载荷使用更多字节,但也为您提供了更多的灵活性(如果您需要也发送其他标志?)
希望对您有所帮助!
如果作为服务器的客户端应该为他们的加密密钥重新设置密钥,我正在尝试使用 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
rekey 标志似乎设置正确,但在尝试获取长度时,它总是以错误的数字结束。
编辑:我应该澄清我的意思是最高有效位,而不是第一位
payloadLength &= 1UL << 0;
会将除第一个以外的所有位归零。
payloadLength &= ~1UL;
会将第一位归零。
让我们看一下这段代码:
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
接下来,有一个问题是关于您尝试读取的是哪一位。看起来您正在尝试读取数字的 least-significant 位。如果是这种情况,您不需要包含任何移位,因为按零位移位没有任何效果。让我们删除那些,给这个:
/* CAUTION: This still has errors! */
payloadLength = ntohl(payloadLength);
short bit = payloadLength & 1U; // get first bit
payloadLength &= 1UL; // set first bit to 0
您提取数字最后一位的代码是正确的。它会屏蔽除最低位以外的所有内容,然后将值存储在变量 bit
中。 (出于好奇,是否有任何理由将其存储为 short
?如果您正在寻找布尔值 "do I need to reencode this?,",您可能只想使用 bool
并写一些东西喜欢
bool reencode = (payloadLength & 1U) != 0;
不过,这由您决定。)
但是,您清除最后一位的代码不正确。现在,当你写
payloadLength &= 1UL; // set first bit to 0
你实际上做的与你的意图相反 - 你正在清除每一位 除了第一个。那是因为如果您将 payloadLength
与一个值进行 AND 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 位来编码是否重新加密。如果您对此表示满意,那就太好了!您无需执行任何操作。
另一方面,如果这是个问题,您有几个选择,我会留给您 select 来自:
不使用 least-significant 位,而是使用 most-significant 位。但是,如果您尝试发送大小为 231 或更大的有效载荷,这将导致问题。
使用least-significant位,但让数字的高31位代表实际负载长度。要提取有效负载长度,只需将所有内容移动一个位置即可。不过,它的缺点是不支持大小为 231 或更大的有效载荷。
根本不要使用这些位来编码!相反,发送有效载荷长度,然后让有效载荷以 header 开头,告诉您是否重新加密等。这每个有效载荷使用更多字节,但也为您提供了更多的灵活性(如果您需要也发送其他标志?)
希望对您有所帮助!